Command line uglify-js
Recently I was working on a small project where I wanted to get some jquery-like functionality in an javascript application but I wanted to keep the downloads as slim as possible. I used zepto.js for the query features: the minified copy of zepto is about 1/4 the size of recent versions of jquery 1.x. But zepto is split into a number of modules, some of which aren’t necessarily included in the default zepto distributions (things like ajax and effects aren’t in the core distribution of Zepto). So I needed to concat together several modules of zepto.js and minify/uglify the code to reduce its size. Didn’t want to take the time to create a package.json and a Gruntfile to do the building; just wanted to download zepto and walk away with a minified copy of the code that I needed.
Many npm packages come with support for command line execution, and uglify-js is one of them. I found that npm will install requested packages without having a package.json file present – it’ll complain a little bit, but it will do it:
$ npm install zepto uglify-js /Users/curious1/prog/javascript/zepto |-+ uglify-js@3.0.27 │ |-- commander@2.11.0 │ |-- source-map@0.5.6 |-- zepto@1.2.0 npm WARN ENOENT ENOENT: no such file or directory, open '/Users/curious1/prog/javascript/zepto/package.json' npm WARN EPACKAGEJSON /Users/curious1/prog/javascript/zepto No description npm WARN EPACKAGEJSON /Users/curious1/prog/javascript/zepto No repository field. npm WARN EPACKAGEJSON /Users/curious1/prog/javascript/zepto No README data npm WARN EPACKAGEJSON /Users/curious1/prog/javascript/zepto No license field. |
Without doing a ‘npm init’ to create a package.json file, npm created the usual “node_modules” directory with the requested packages (as well as the ones those packages are dependent on):
$ ls node_modules commander/ source-map/ uglify-js/ zepto/ |
The Zepto package comes with the default minified and unminified versions in the dist/ directory, and the extra (and unminified) modules in the src/ directory:
$ ls node_modules/zepto MIT-LICENSE README.md dist/ package.json src/ $ ls node_modules/zepto/dist zepto.js zepto.min.js $ ls node_modules/zepto/src ajax.js deferred.js fx.js ios3.js zepto.js assets.js detect.js fx_methods.js selector.js callbacks.js event.js gesture.js stack.js data.js form.js ie.js touch.js |
The uglify-js module came with an executable Node command line script in the typical bin/ directory:
$ ls node_modules/uglify-js/bin uglifyjs* $ ls -l node_modules/uglify-js/bin/uglifyjs -rwxr-xr-x 1 curious1 staff 14325 Jul 29 14:44 node_modules/uglify-js/bin/uglifyjs* $ file node_modules/uglify-js/bin/uglifyjs node_modules/uglify-js/bin/uglifyjs: a node script text executable $ head node_modules/uglify-js/bin/uglifyjs |
(it’s worth noting at this point that I have the ‘ls’ command aliased to ‘ls -CF’ in my bash shell: this causes “*” to be printed after executable files and a “/” after directories)
The help message for the ‘uglifyjs’ command lists the options that I need:
$ node_modules/.bin/uglifyjs --help Usage: uglifyjs [options] [files...] Options: -V, --version output the version number -p, --parse Specify parser options. -c, --compress [options] Enable compressor/specify compressor options. -m, --mangle [options] Mangle names/specify mangler options. ...more output... |
I used curly brace syntax to select the zepto module files that I want under the “src/” directory:
$ uglifyjs node_modules/zepto/src/{zepto,event,ajax,form,ie,fx,fx_methods,detect,touch,gesture,ios3}.js \ -m -c -p 1 --source-map zepto.x.map.js > zepto.x.min.js ...no output.. |
The result: a concat’ed and minified zepto.js (named “zepto.x.min.js” for “eXtended”):
$ ls -l zepto.x.min.js -rw-r--r-- 1 curious1 staff 34564 Aug 8 15:22 zepto.x.min.js |
The resulting minified .js file is slightly bigger than the one that comes in the default distribution, but it includes the features like ajax support, event handling, easing effects that I need and that aren’t in the default distribution.
Just taking a peak inside the minified code: uglification removes a lot of newlines, so the final file contains just a very few long lines. I used ‘cut -c1-200’ to show just the first 200 characters of each line:
$ cut -c 1-200 zepto.x.min.js var Zepto=function(){function t(t){return null==t?String(t):W[Y.call(t)]||"object"}function e(e){return"function"==t(e)}function n(t){return null!=t&&t==t.window}function i(t){return null!=t&&t.nodeTy e&&(h.el.trigger("swipe"),h.el.trigger("swipe"+e))}).on("touchstart MSPointerDown pointerdown",function(e){(v=a(e,"down"))&&!o(e)||(g=v?e:e.touches[0],e.touches&&1===e.touches.length&&h.x2&&(h.x2=void //# sourceMappingURL=zepto.x.map.js |
npm packages typically come with other things like a LICENSE file and a README.md (“markdown”) file:
$ ls node_modules/uglify-js/ LICENSE README.md bin/ lib/ package.json tools/ |
It’s often worth skimming the README.md files that come with npm packages: they often provides valuable documentation and examples on how to use a tool.
For larger development projects and/or projects involving multiple contributors, a more structured project might be necessary (package.json, grunt or gulp to automate the copy/concat/uglify process). But for simple projects (or just some exploration and experimentation) it’s useful to have the command line tools available!
TL; DR
Set up a project quickly to experiment with npm Javascript packages (no npm init):
$ npm install zepto uglify-js |
Found executable forms of the code package under the “bin/” directory:
$ ls node_modules/uglify-js/bin |
Using some standard Linux tools to learn about the runnable code:
$ ls -l node_modules/uglify-js/bin/uglifyjs $ file node_modules/uglify-js/bin/uglifyjs $ head node_modules/uglify-js/bin/uglifyjs |
Checking command line options for ‘uglifyjs’ with “–help” (a “help” arg may also work depending on the package):
$ node_modules/uglify-js/bin/uglifyjs --help |
The zepto source modules were under a “src/” subdirectory:
$ ls node_modules/uglify-js/src |
Invoking ‘uglifyjs’ to build and minify the custom js file:
$ uglifyjs node_modules/zepto/src/{zepto,event,ajax,form,ie,fx,fx_methods,detect,touch,gesture,ios3}.js \ -m -c -p 1 --source-map zepto.x.map.js > zepto.x.min.js ...no output.. |
Examining the minified/uglified .js file:
$ cut -c 1-200 zepto.x.min.js |
References
npm: “the package manager for JavaScript”
uglifyjs: “a JavaScript parser, minifier, compressor or beautifier toolkit”
zeptojs: “the aerogel-weight jQuery-compatible JavaScript library”
Versions
$ npm -version
3.3.6
$ node –version
v5.0.0
$ npm list –depth 0
/Users/curious1/prog/javascript/zepto
|– uglify-js@3.0.27
|– zepto@1.2.0