Monday, 24 April, 2017 UTC


Summary

Every developer will love this saying "It is hard to build a software without using a build tool." To get rid of the repetitive tasks, we are using build tools. If you think Gulp has killed Grunt you may want to think about another tool because npm has surpassed both.
Now Node provides a great way to implement a build process with only npm.
Imagine a situation where using build tools makes you horrible, I felt the same thing when I use Grunt and Gulp. Now that I have been using npm as a build tool, I feel more comfortable. Here I will share with you how to do the same and make yourself comfortable while using the build tool.
At the end of this article, we will be making our own boilerplate.
Drawbacks of using others:
When using Grunt or Gulp, the packages specific to that build tool are usually just wrappers on the main package. For instance, gulp-sass is really a Gulp specific wrapper to node-sass. We can go straight to the source and just use node-sass with npm!
There are drawbacks of using Grunt/Gulp specific packages.
  1. We need to watch the versions of each sub modules which we are using. If anything gets updated or removed we have to look for another one to achieve the same. But here with npm, no such problem will come.
  2. Adding new tasks into build tool will increase dependencies. But here we can use normal command prompt command like '&&' to combine multiple tasks.
  3. Custom script file like (Gruntfile.js) for tasks. Here only package.json file is enough.
  4. Doesn't support any commands which we use in command prompt. Here you can use all commands into your package.json file.
Types of npm scripts
  1. Default scripts
  2. Custom scripts
Getting started
Let's start our build commands!
  1. Create an empty directory and initialize it as npm using npm init. It will ask you to construct your package.json file. If you feel lazy like me to hit enter many times, then go with shorthand script npm init --yes.
  2. Now check your directory, a package.json file gets created like this :
{
  "name": "your_directory_name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
  1. By default, a test script will get created inside the script object. Inside the script object, we are going to configure our tasks.
  2. Run the default task using npm test shorthand for npm run test
It states that node_modules missing. We have to add our dependencies.
  1. Let's install dev-dependencies first :
$ npm i -D jshint lite-server mocha concurrently node-sass uglify-js
  1. Let's start creating our scripts :
"scripts": {
  ...
  "dev": "lite-server"
}
npm run dev - I have used it as a development server. It will take care of live-reloading and Browser-sync (since it is sub-module of lite-server, no need to install it separately). We don't need to configure a watch property for all your files like (HTML, CSS, JS).
Browser-sync will help you with cross-browser checking. To know more about lite-server refer docs.
  "scripts": {
    ...
    "db": "json-server --watch db.json --port 3005"
  }  
npm run db - If you want to know more about JSON-Server refer my article.
  "scripts": {
    ...
    "start": "concurrently -k \"npm run dev\" \"npm run db\""
  }  
npm start shorthand for npm run start. Concurrently, using it we can perform two tasks simultaneously. You can also combine both the tasks using '&&' operator. To know more about it refer docs.
  "scripts": {
   ...
   "uglify": "mkdir -p dist/js && uglifyjs src/js/*.js -m -o dist/js/app.js"
  }  
npm run uglify - It will minify your JavaScript files and move it into your desired directory. It will create a new folder only if it does not already exist (-p flag).
  "scripts": {
    ...
    "lint": "jshint src/**.js"
  }  
npm run lint - It will look for any JavaScript files inside the source folder and helps detect errors and potential problems in your JavaScript code.
"scripts": {
  ...
  "sass": "node-sass --include-path scss scss/main.scss assets/main.css"
}
npm run sass - It allows compiling your .scss files to CSS automatically and at a good speed.
"scripts": {
  ...
  "test": "mocha test"
}
npm test shorthand for npm run test. Mocha is a JavaScript test framework, which helps you to write test cases.
"scripts": {
  ...
  "bash": "Location of the Bash/Shell script file"
}
npm run bash - If you think you're making a lot of commands inside the scripts object, you can make it as Bash/Shell script and include it in your package.json file as like above.
Boilerplate
So far we have seen the basic npm build commands and explanation for them. Let's start to prepare our own boilerplate. Using this boilerplate will save your time on preparing build tool. Invest more time on building your app.
"scripts": {

  "start": "concurrently -k \"npm run dev\" \"npm run watch-css\"",

  "dev": "lite-server",
  "db": "json-server --watch db.json --port 3005",

  "build-js": "mkdir -p dist/js && uglifyjs src/js/*.js -m -o dist/js/app.js",

  "lint": "lint jshint src/**/**.js",

  "build-css": "node-sass --include-path scss scss/main.scss assets/main.css",
  "watch-css": "nodemon -e scss -x \"npm run build-css\"",

  "test": "mocha test",
  "pretest": "npm run lint",
  "posttest": "echo the test has been run!",

  "bash": "Location of the bash/shell script file"
}
This boilerplate will take care of all the necessary things which we need during development phase like:
  1. npm run dev- Bootstraps our app, opens it in the browser, reloads the browser whenever we make changes in source.
  2. build-js- Minifies all our JavaScript files, which will be needed during production.
  3. watch-css- Nodemon is a utility that will monitor for any changes in your source and automatically restart your server. Here I have used it to monitor for any changes in the .scss file, if there are changes, it will restart the server and build our css.
"scripts": {
  "test": "echo I am test",
  "pretest": "echo I run before test",
  "posttest": "echo I run after test"
}
  1. npm test- It wraps the above three commands "pretest test posttest" and executes them in the order I have listed. Initially when you hit npm test it will look for pretest command. If it is there, it gets executed first, followed by test and then posttest. During the look up if it doesn't find pretest command it will directly execute the test command.
The remaining commands I have explained it in the previous section. You can also customize this boilerplate based on your needs.
Conclusion
I hope this article has saved your time while preparing a build tool. Now we have prepared our own boilerplate for npm as a build tool. I hope now you will accept npm has killed both Grunt and Gulp. Feel free to use my boilerplate and contributions are welcome. Further, you can refer official npm scripts.
If you have any queries, please let me know in comments.