-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update minifier.js to remove server and development code #10056
Conversation
A very simple change inspired by https://github.com/ssrwpo/uglifyjs2 to remove server (`Meteor.isServer`) and development code (`Meteor.isDevelopment`) easily (and speeds up client-side execution by removing `Meteor.isClient` and `Meteor.isProduction`) We do this by search-replacing first to get simple var names (UGLIFYJS_FALSE and UGLIFYJS_TRUE) for `terser` to replace during conditional compilation Notes: 1. In addition to reducing JS load, removing server-side code is desirable for security purposes (and protecting server-side code as well) 2. Tested in production and works great
packages/minifier-js/minifier.js
Outdated
@@ -7,13 +7,18 @@ meteorJsMinify = function (source) { | |||
terser = terser || Npm.require("terser"); | |||
|
|||
try { | |||
source = source | |||
.replace(/Meteor\.isServer|Meteor\.isDevelopment|process\.env\.NODE_DEBUG/g, 'UGLYFYJS_FALSE') | |||
.replace(/Meteor\.isClient|Meteor\.isProduction/g, 'UGLYFYJS_TRUE'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should actually just be able to put these expressions in the global_defs
map below, so you don't have to use a regular expression, and the minifier can replace the actual expressions in the AST—much safer!
Ok, creating a new PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried using global_defs but terser missed quite a few Meteor.isClient
-- this method of doing manual replace prior to terser didn't miss any
Also, to avoid passing affected source to Babel in case of failure by terser, we created a separate variable
I like the idea of eliminating unused code, but I'm worried that these regular expressions are not accurate enough for a global replacement. Maybe this is a contrived example, but the below code would be a false positive:
False negatives aren't so risky, but just for an example to show it can also happen:
|
I agree that these regexp can be improved. Is the only concern in your view that we have someone being non canonical and creating objects with 'Meteor' as field? In some cases, we can't help people from hanging themselves. I can work on the regex some more |
I think there are other ways this can cause unexpected behavior. I just put the first example that came to mind. Here is a more realistic one:
This react element could be in an application that teaches people how to use Meteor, but the static text string would get modified by the minifier with the proposed change. In which cases was |
It's hard to say where terser failed as the code was minified (and frankly, didn't feel like trying to untangle), we had quite a few Indeed, there are many cases where regexp fails, I was oversimplifying as I was blindly looking at our app. Edge cases should be few, but a platform like meteor should take care of them. It's more complex than I bargained for. Maybe just maintain our fork of the package ... |
Just to be perfectly clear: using a |
@benjamn just wondering, but why is that? Shouldn't removing isServer code from the client be save for all applications? What issues could we face here? For us this change would be a quite big improvement (didn't measure, but I think roughly 10% of our client bundle is Meteor.isServer code). |
maybe facebook's prepack would be a nice solution to that (when it's ready someday...) |
I was having a look at this, and there is a great babel plugin While not part of minification, it might make sense to configure this plugin as part of We could configure it to replace all the Example setting that would replace all
[1] |
|
@ramezrafla are you still interested in working on this? Otherwise I'd be willing to continue where this left of. It still would need another solution than the regex replacement. Preferably with terser alone, if that's not possible then what @nathan-muir suggests sounds promising, but performance impact should be looked into. |
@sebakerckhof, I am really sorry for delay. |
Oops -- sorry. I didn't realise this feature would be community-driven. |
The CLA is still not signed here, because of that I'm closing this PR. @ramezrafla and @sebakerckhof feel free to continue the work in a new PR as we can't merge this one without the CLA. |
A very simple change inspired by https://github.com/ssrwpo/uglifyjs2 to remove server (
Meteor.isServer
) and development code (Meteor.isDevelopment
) easily (and speeds up client-side execution by removingMeteor.isClient
andMeteor.isProduction
)We do this by search-replacing first to get simple var names (UGLIFYJS_FALSE and UGLIFYJS_TRUE) for
terser
to replace during conditional compilationNotes: