How to pass uglifyjs options to standard-minifier?


#1

Hi,

We were using ssrwpo:uglifyjs for minification. The way we configured this was in the package.json with uglifyjs2 key as mentioned here.

We are now upgrading to latest meteor 1.7 but due the ssrwpo:uglify package has some version constraints (mostly babel) are hence removed it.

We now installed standard-minifier & minifier-js packages. But need to know how to configure the uglify options for this package. There is no such documentation here.

Can someone help?

Thanks,
Nilesh


#2

Is there anyone in the Meteor community that can shed some light on @nileshparab 's question? We are having a similar dilemma that is causing some real headaches. If we can’t configure uglifyjs options is there anyway to exclude a certain library from being minified by standard-minifier-js ?

mapbox-gl dies when going through the meteor stanard-minifier-js and we are unable to figure out what the best approach is to either exclude it or get it working with the minification process meteor currently has.

Thanks,

Darren


#3

After investigating this issue I came up with a very hackish way of dealing with the issue of passing Uglify options for now. I’m running meteor 1.7.

Here’s what I did for a temporary hack fix:

  1. Install standard-minifier-js as a local package (https://github.com/meteor/meteor/tree/devel/packages/standard-minifier-js). This can be done by creating a copy of standard-minifier-js in your /packages directory so that you are using the package locally.

I created a folder called “modified-minifier-js” in my /packages directory and pasted a copy of the standard-minifiers-js into that directly. I updated the package.json file to the new name modified-minifier-js.

  1. Add the new modified-minifier-js package to your meteor packages file.

  2. Run meteor with the--production flag set so it runs through the minification process.

After running the app it will create a file in [your app]/.meteor/local/isopacks/modified-minifier-js/plugin.minifyStdJS.os/packages called minifier-js.

  1. Edit the minifier-js file to pass in the options you prefer to Uglify. Apparently this is where the default options meteor is assuming we want to be set:
    var uglifyResult = uglify.minify(source, {
      compress: {
        drop_debugger: false,
        unused: false,
        dead_code: true,
        typeofs: false,
        global_defs: {
          "process.env.NODE_ENV": NODE_ENV
        }
      },

I added typeof: false to this compress options.

If anyone is trying to get mapbox-gl working with meteor you need to set the compression option of “typeofs” to false.

After that restart meteor again and it will run through the minification process with your new options passed into the uglifier.

This also kept that setting when I deployed to production using mup.

This works for now but is a hack. I hope to be able to find or have suggestions from the community on how to better approach this so that we can pass custom options into uglify.

Is there a reason why we are not able to pass custom options to uglify js ? Perhaps we can but I’m unaware of how to do that in a better way?

Any recommendations on approaching this better would be appreciated.


#4

So I had a quick look through the relevant Meteor packages standard-minifier-js and minifier-js and found a couple of things:

  1. standard-minifier-js skips files that already have the .min.js suffix:

Which gives you an easy escape hatch if an individual file is giving you trouble.
Sadly it looks like mapbox-gl doesn’t have a .min.js file in their npm bundle


  1. The UglifyJS options are set in minifier-js:

So you could make a local override of that package to set your own options (or configure it to look at your package.json). Just copy/clone as submodule it into /packages and edit away


The other option would be to fork the original ssrwpo:uglifyjs package to bring up to date with Meteor 1.7
just bump the versions in both package.js files (ssrwpo:uglifyjs and it’s dependency ssrwpo:minifierjs) and see if it works. I can’t see anything that would fail as a result of those constraints


#5

Thank you for sharing the workaround. This will definitely work for us as well. One doubt I have with this is:

You are overriding the minifier-js package from app/.meteor/local folder. This folder & its contents are always recreated during build. So we have not added the local folder to git. However we have added .meteor folder as it holds all package information. Do you have your local folder commited to git?

Your & @coagmano analysis is correct standard-minifier-js package does not allow passing options from package.json.

I also checked ssrwpo:uglifyjs2 package, they have code to read options from package.json. Here is the util they are using & the call to it from here.

I will try overriding the minifier-js package that standard-minifier-js uses internally. I am not however sure if this will work because I will be using standard-minifier-js from meteor & its dependency minifier-js locally.


#6

@coagmano thank you helping. I actually had overriden the ssrwpo:uglifyjs package locally. But removed it because it was not working probably or I did it the wrong way.

The incident that led me to conclude that overriden package was not working was the react warning that pointed out This page includes extra development build of React shown by React Dev Tool extension. I was running the server with --production flag. I thought that build is not minifying the app correctly which is why this warning is triggered.

Below is what I did to override the package:

  • Cloned the package folder & copied it to app/packages. Did not rename the folder.
  • Removed the package’s entry from app/.meteor/packages & app/.meteor/versions files.
  • Update the babel constraints as required in the package.

#7

@coagmano got why my overridden ssrwpo:uglifyjs package was not working. I was not renaming the cloned & adding it to app/.meteor/packages file.

Confirmed this when I overrode the minifier-js & standard-minifier-js packages.

@systemlevel confirmed that providing local package to a atmosphere package does not work, because we cannot keep the name of overridden packages same as atmosphere packages.

I am planning to continue to use standard-minifier-js in place of ssrwpo:uglifyjs as its inactive since almost a year.

Will try integrating the similar package.json config from ssrwpo:uglifys to standard-minfier-js.


#8

Overriding an atmosphere package with a local of the same name is supposed to work.
I do it fairly regularly while waiting for bugfix PRs to be merged

I never remove the package from /.meteor/packages though


#9

We made a change to minifier-js to remote server and development code with minifier-js: https://github.com/meteor/meteor/pull/10056

Upvote this PR if interested!


#10

@coagmano yes you are right. I was doing a mistake initially when I removed the entry from .meteor/packages. I tried with keeping the name same & entry in .meteor/packages file & it worked.

@ramez that was great. You may also consider this from the ssrwpo:uglifyjs:

  • File removal to remove files like packages/ddp-server.js & packages/shell-server.js.
  • Terser options configurable from package.json.
  • aggressive minification by calling meteorJsMinify on combined minified js (stored in toBeAdded.data).

We have done this in our custom package. Wrote the code in hurry, but currently we are testing it & about to go live shortly with that.


#11

Did this result in substantial reduction in bundle size? If you look at the bottom of the github terser Github readme there is a table comparing options vs size of output. You will see that the majority of savings are due to removing white spaces. Aggressive minification may not have such a profound impact.

Removing server-side code however will have an impact on size (you would otherwise have all your server code bundled in your JS) and of course securing and protecting IP.


#12

@ramez aggressive minification did not result in substantial reduction (i got close to 1KB of reduction) but it garbled the statements like Package.meteorInstall which were visible in the client bundle downloaded on browser.