Fast minifier with source maps

The slowest part of production builds for many apps is minifying. I’ve released version 4 of zodern:standard-minifier-js to improve this.

Version 4 adds caches so it only minifies files that were modified since the previous production build. One app that had spent 198 seconds minifying now takes 50 seconds during a normal deploy, and another app that had spent 596 seconds now takes 71 seconds.

Besides being fast, the other main feature is creating production source maps. Production source maps can be used with an error tracking service (such as Monti APM, Sentry, or Rollbar) to show better error stack traces. This is unchanged, and works the same as in version 3.

To switch the minifier used by your app, run:

meteor remove standard-minifier-js
meteor add zodern:standard-minifier-js
meteor add zodern:hide-production-sourcemaps

How much time the cache saves depends on what changed since the last build. For example, after updating npm dependencies used on the client, minifying will take longer during the next production build compared to only modifying app code. If you are deploying from CI, you must configure the CI to cache some of the folders in .meteor/local. I wrote a general guide here on how to set it up.

Calculating the size of modules for the bundle-visualizer can add up to 30+ seconds to a production build. Since this is unnecessary during a deploy, you can set the environment variable DISABLE_CLIENT_STATS=true to disable this step. With this set, the improved times above would be an additional 12 - 25 seconds faster.

Other changes:

  • Includes all of the improvements in standard-minifier-js up to Meteor 1.11
  • Compatible with Meteor 1.6 and newer (1.4 - 1.5 were dropped since newer versions of Terser are not compatible)

If anyone who maintains a minifier wants to add caching, you can use the zodern:caching-minifier package.

33 Likes

Awesome work as always.

1 Like

Absolutely fantastic! 50% off our build times (on Github Actions)!

Does anyone have a “Sentry-upload-sourcemaps” script?

1 Like

@zodern After switching to these 2 packages Chrome shows these console notifications. I tried 2 different live projects. After reverting back to the standard minifier, console stays clean.

This would be gold!

Or even a recent guide on how to do it manually :confused:

This is normal. Meteor puts the URL for the source map in each dynamically imported file. When you open the dev tools in production, it tries to download all of the source maps, but since the zodern:hide-production-sourcemaps package blocks that it fails There is no downside besides the extra logs after opening the dev tools.

When using the standard js minifier Meteor doesn’t add the URL’s to the files since the minifier doesn’t create source maps.

1 Like

Hi @zodern, I’ve reported a bug, or what I think is a bug, in zodern:standard-minifier-js on github a couple of days ago: https://github.com/zodern/minify-js-sourcemaps/issues/24

It seems that source files won’t get minified if part of a dynamic import. Let me know if I should pass a link on to you to demonstrate it.

Here’s how I upload sourcemaps to Sentry. This is part of my CI workflow (I use Semaphore CI). Works well for me. Internal Meteor packages don’t have sourcemaps, not sure if that’s fixable or not, but all my code has sourcemaps applied in Sentry which is very helpful. I don’t use dynamic imports so can’t comment on that.

Env var setup:

SENTRY_ORG=my-org
SENTRY_PROJECT=my-proj
SENTRY_NO_PROGRESS_BAR=1
SENTRY_AUTH_TOKEN=3265784395674...

Script:

curl -sL https://sentry.io/get-cli/ | bash
RELEASE_NAME=$( echo ${SEMAPHORE_GIT_TAG_NAME:-${SEMAPHORE_GIT_SHA:0:7}} )
sentry-cli releases new $RELEASE_NAME
sentry-cli releases files $RELEASE_NAME upload-sourcemaps --rewrite bundle/programs/web.browser
sentry-cli releases files $RELEASE_NAME upload-sourcemaps --rewrite bundle/programs/web.browser.legacy
sentry-cli releases files $RELEASE_NAME upload-sourcemaps --rewrite --url-prefix '~/__cordova' bundle/programs/web.cordova

Also related to this – to fix Cordova HCP (due to this issue), I have the following in my build steps just after the bundle is built:

install-package jq   # replace with apt-get or whatever
jq 'del(.manifest[].sourceMap) | del(.manifest[].sourceMapUrl)' bundle/programs/web.cordova/program.json > program.json.tmp
mv -f program.json.tmp bundle/programs/web.cordova/program.json
2 Likes

Hi @zodern

With zodern:hide-production-sourcemaps and meteor 2.0.beta.4, it seems that the package work for production AND development build. Where is the catch ?

Thanks for the hint… and this beautiful package.

Hi @zodern , excellent work! I am trying to summarize the difference with Meteor standard minifier:

Meteor:

  • it does compute stats.json on every production and dev build?
  • it’s slower
  • it allows to see source maps in production, which you may don’t want it doesn’t produce production source maps at all (so goodbye decent errors on Sentry)

Your package:

  • you add an option to disable computing the stats.json, that doesn’t exist in Meteor? (I am not sure I’ve fully understood this part). So you may want to set DISABLE_CLIENT_STATS=true all the time, except when explicitly including “bundle-visualizer” for debugging?
  • since now you create production sourcemaps, you add another package to disable loading the sourcemaps from the app. Does it also improve performance? Or at least reduce bandwith?
  • it’s faster, mostly thanks to caching? Or the minifier is also faster?

I remember in the past having trouble with Uglify when bundling code that is already minified (can happen accidentally with vendor code)

1 Like

Reviving this old thread I know - hoping to get some help with Sourcemaps that I still haven’t figured out.

My steps (I am using : zodern:standard-minifier-js as well as zodern:hide-production-sourcemaps

  1. Deploy Meteor code to Galaxy
  2. Create a new Sentry release:
    sentry-cli releases new V123 --org ORG_NAME --project PROJECT
  3. Upload sourcemaps for that release:
    sentry-cli releases files V123 upload-sourcemaps ./.meteor/local/build/programs/web.browser --org ORG_NAME --project PROJECT
  4. Finalise the release:
    sentry-cli releases finalize V123

All the steps run as expected: Sourcemaps are successfully uploaded to the specified release.

However I still get cryptic errors like: TypeError: _jp.aowzjio is not a function

Anyone have any pointers on what I may be doing wrong/how I can debug this?

Thanks in advance!