Page MenuHomePhabricator

ResourceLoader minifier outputs invalid javascript for mw.cx.dashboard module
Closed, ResolvedPublic

Description

Problem

The minified javascript coming from RL is invalid and browser throws parsing error

How to reproduce

Go to en.wikipedia.org, open browser dev tools console, and write

mw.loader.using('mw.cx.dashboard')

This will load mw.cx.dashboard RL module, minified.

image.png (110×700 px, 31 KB)

Immediately after the module is loaded, you will see a js error as showin the above screenshot.
The error is coming from a line in code with throw statement, a new line was inserted after throw statement

image.png (423×644 px, 134 KB)

new lines are not allowed after throw as per https://www.ecma-international.org/ecma-262/5.1/#sec-12.13

If we do the above steps in https://en.wikipedia.org/wiki/Main_Page?debug=1 there wont be any js error, indicating the error is only present in minified javascript non-debug mode.

Additional Information

The exact code where the minification fails is a js library(banana-i18n) which was used a npm dependency for mw.cx.dashboard RL module built by vue-cli. The mw.cx.dashboard source code is already minified by vue-cli, so one could argue there is two minification here, but I don't think that can cause this problem because JavaScriptMinifier.php is supposed to be agnostic about the formatting of input javascript. (Should there be an option in RL to skip minification in these contexts?)

Expected result

Minifier should produce valid javascript.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

Original code before RL minification, from

https://en.wikipedia.org/w/load.php?debug=true&only=scripts&modules=mw.cx.dashboard

Simplified snippet
emitter=new class{ /* … */ extlink(t){if(2!==t.length)throw Error("Expected two items in the node");} }

I will try to write a minimal test case, however, it is possible that the reason this fails is that the file is using syntax not allowed in ES5 grammer, such as class and let. These are not currently allowed in production by default per T178356.

ResourceLoader does not yet have minification support for them either. However you can disable the minification step by adding /*@nomin*/ at the top of the file, or in a separate file loaded before it in the same module. Note though that if you do this, you will need to make sure that the module as a whole is never loaded unless an ES6 feauture test was passed as otherwise this would cause fatal errors for users.

Krinkle triaged this task as Medium priority.Jun 22 2020, 8:01 PM
Krinkle moved this task from Inbox to Backlog on the MediaWiki-ResourceLoader board.
santhosh claimed this task.

Closing this since we did the workaround of adding /*@nomin*/

For sake of transparency: Per my understanding, the conclusion is that this only happens for ES6 code, which is not supported by the minifier. The recommended workaround is @nomin for anyone using ES6 code in a resource loader module. Minifier support for ES6 will be done as part of general ES6 support in resource loader, hence this ticket can be closed.