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.

31 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.

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