Advanced front-end automation

with npm scripts
@k88hudson
Mozilla
<3 @brycebaril @dark_rost_ruth
Who writes code for browsers?
I love browsers
I hate build tools
“Systems tend to grow, and as they grow, they encroach”

“Systems tend to expand to fill the known universe.”
—John Gall, The Systems Bible
The more complex and self-sufficient the
automated system, the more difficult it
will be understand and operate.
The Paradoxes and Ironies of Automation, David Wentzel. 

http://www.davewentzel.com/content/paradoxes-and-ironies-automation
1. Takes advantage of the natural interface presented

by its component parts;
2. Breaks down complex things into simple,

composable things;
3. Makes compromises intentionally, not
circumstantially
Your system can win, if it:
Why npm scripts?
npm scripts =
shell + node + npm =
magic
npm scripts can:
transpile es2015, transpile jsx, minify/optimize code, optimize svgs, copy,
rename and move files, compile css via a pre-processor, add autoprefixing,
source maps for js/css development, build Android and Firefox OS apps from
source with cordova, run unit tests, run code linting, run style checking,
run test coverage reporting, deploy releases, run watch for developer
environment and live reload dev server, etc. etc. etc.
in twenty lines or less, with zero plugins.
Let’s dive in!
Why is the npm script environment
better at dealing with our problems?
You already use node, npm
npm run
package.json usage
npm run
package.json usage
npm run environment
node executables via npmshell $PATH
{npm lifecycle
bash/cmd.exe -> good at:
File i/o
Chaining tasks
Running tasks in series/parallel
Cross-compatible!
rutabaga input.js | uglifyjs > output.js
tomato && cucumber && cauliflower
bash / node
cat / catw
mkdir / mkdirp
rm / rimraf
& / npm-run-all —parallel
npm run: $PATH
Works!
A good automated system takes advantage of the

natural interface presented by its component parts
Plugins add an extra layer
Most tools already have a cli
browserify
webpack
mocha
lessc
joshing
eslint
sass
uglifyjs
svgo
karma
Browserify
“browserify -d -t reactify ./entry.js -o ./output.js”
module.exports = function(grunt) {
grunt.initConfig({
browserify: {
options: {
debug: true,
transform: ['reactify']
},
files: {
'./output.js': './entry.js'
}
},
});
grunt.loadNpmTasks('grunt-browserify');
grunt.registerTask('default', ['browserify']);
};
Webpack
npm run environment
node executables via npmshell $PATH
{npm lifecycle
Lifecycle scripts
npm install
npm publish
npm version
npm version patch -m "Upgrade to %s for lolz"
> commit 522d0 “Upgrade to v0.0.1 for lolz”
> new tag v0.0.1
"scripts": {
"preversion": "npm run test && npm run build”,
"postversion": "npm publish && git push --tags"
}
pre- and post-
npm run potato
> prepotato
SO HUNGRY
> potato
mashing...
done.
> postpotato
YUM YUM
A good automated system breaks down
complex things into simple, composable things
http://www.infoq.com/presentations/Simple-Made-Easy
“Simple Made Easy”
Components of an automated system are simple

when they have a single, well-defined objective.


Good complex tasks are composed

of well-defined simple ones.
Baseline
Sub-tasks
Sub-tasks with npm-run-all
Name-spaced sub-tasks
Complete example
What are the trade offs?
Simpler mental models instead of
performance.
Less code, but less extensible
Shell scripting is still hard, especially
maintaining cross-compatibility with Windows.
We need to build more tools, a

set of common “recipes”… and more?
What can you do?
- Try it out, talk about what’s hard
- Work on cross-platform bugs
- Share your recipes
- File bugs or help improve npm docs
Go forth and script!

Show me what you build @k88hudson

Advanced front-end automation with npm scripts