In this post we will see how it is possible to configure an entire build sequence using npm only.
What we want to achieve:
One command npm run package
should:
- clean our build folder
- compile our css from stylus
- compile our html from jade
- bundle and minify our javascript
1) Minimal project structure
Let’s assume our project is organized as follows:
|-- dist // Build will end up here |
2) Compile our CSS and HTML
Stylus to CSS
We can compile our stylus with the following command:
stylus src/stylus/site.styl --out dist/
Let’s set this up in the package.json: Read this post if you want to know the basics of setting up scripts in npm.
Jade to HTML
In a similar fashion, we can compile our Jade templates to HTML using the following command:
jade src --out dist/
Add the npm tasks
In our package.json, we can now create the tow following scripts:
"scripts": { |
3) Bundle and minify the JavaScript
Bundle with browserify
(Here is an introduction to browserify if needed)
The command to bundle our JS into one file is browserify ./src/js/main.js -o ./dist/bundle.js
Minify with uglify
I am using uglifyJS2 for this task.
The task to minify the bundle.js file is uglifyjs -- compress ./dist/bundle.js -o ./dist/bundle.min.js
Piping the two
Now what we want is to pipe the output of the browserify task into the uglify task so that we can combine both into one npm task
To do this, we are going to use a unix pipe |
and connect the STDOUT of the first task with the STDIN of the second.
browserify ./src/js/main.js | uglifyjs --compress > ./dist/bundle.min.js
Let’s set it up as a npm task:
"scripts": { |
4) Putting everything together
Now let’s combine all our tasks in one npm package
task:
"package": "npm run package:stylus && npm run package:jade && npm run package:js"
This will run our 3 package tasks in a sequence.
"scripts": { |
Run npm run package
to test the full build sequence.
5) Cleaning up the output directory
Before running the build, we would like to clean the output directory.
We will use rimraf’s CLI like so: rimraf dist/*
.
Instead of creating another ‘package:clean’ task, we can use an npm script prehook. By prefixing an existing task (even custom) with pre or post, it will be automatically executed before or after our main task.
In our current project, if we create a task called <b>pre</b>package
it will be executed automatically before our package
task. In a similar way, <b>post</b>package
would be executed after package
.
Our final task:
"prepackage": "rimraf dist/*"
and here is the final scripts object in he package:
"scripts": { |