Codementor Events

Write Simple Tasks for Development - The Power of NPM Scripts

Published Mar 14, 2019
Write Simple Tasks for Development - The Power of NPM Scripts

Forget about task runners such as “Grunt/Gulp” or bundlers like “Webpack/Parcel” — if all you need is some simple tasks that you can achieve using “npm scripts”.

Let’s imagine that you’re working on a project that requires a couple of simple tasks to be done, before it’s ready for production.

List of tasks:

  • Compile Sass to CSS
  • Generate the source-map files
  • Handle browser’s vendor prefixes
  • Minify the CSS

These tasks can be created with the power of npm scripts, rather than task runners or bundlers. It is cleaner, simpler, has fewer dependencies, no 3rd party plugins/wrappers… Instead, direct use of packages’ CLI.

Our list of tasks, does not even require a single js task, so using Bundler in this case, would be terrible option.

Let me show you, how simple it is!

It is time to create one project, we will call it “dummy-project” and then write all those tasks, using npm scripts that were mentioned above.


Create our first “dummy-project” using Terminal and change directory to it…

cd ~/Sites && mkdir dummy-project && cd dummy-project


Create directory and place us in it…

Now let’s create a package.json file real quick…

npm init -y


Generate the file without any questions…

This file is now generated and we can proceed. Now it is time to install any devDependencies that we require for our mentioned tasks.

In this case, those would be:

  1. Autoprefixer
  2. CleanCSS CLI
  3. NodeSass
  4. PostCSS CLI

To install all of them, we’d run following command:

npm i -D autoprefixer clean-css-cli node-sass postcss-cli


Install dev-dependenices with npm — package manager…

Obviously, since we want to compile for production too, we must also have a task that will clean our production directory… We can use rimraf for this.

Let’s build a structure of our project now…

  • We will have asrc directory for development
  • In our src directory, we will make a file called dummy.scss, which will contain our Sass code with Scss syntax
  • We will have adist directory for production, which will be automatically generated

Time to write those script tasks… Open up package.json file in your favorite code editor, find "scripts" object and remove the "test" property from within it…

* Note, you can name the script commands however you like. This is just the convention that I prefer…

While we are within "scripts" object in our package.json file, we can now start writing our commands.

Clean the “dist” directory

"clean": "rimraf dist",

Compile Sass to CSS from “src” to “dist”

"compile": "node-sass --output-style=expanded --source-map=true src/dummy.scss dist/dummy.css",

Use Autoprefixer to handle browser’s vendor prefixes

"prefix": "postcss dist/dummy.css --use=autoprefixer --map=false --output=dist/dummy.css",

We will need a single addition for Autoprefixer in our “package.json” file and that is to define the browsers that we care about. As said in this post, we will support “last 2 versions” of each browser. We could place the following, right after the enclosing bracket of the"scripts".

"browserslist": ["last 2 versions"],

Handle minification using CleanCSS

"minify": "cleancss --level=1 --source-map --source-map-inline-sources --output dist/dummy.min.css dist/dummy.css",

As you can tell, I left that dangling comma in our last script command. If we were done, that’d lead to an error, when running any npm command.

However, we aren’t done just yet, because we want to make our life easier and for that, we must write two more commands. One that we can use for development and another for production , so that we do not even need to memorize all those given names of our tasks, but instead just these two.

Common practise is to name those two as dev and build… But of course, you can named them however you want.

Command for Development

"dev": "npm run compile -- --watch",

You might find it weird to see an extra -- in this command. If we were using yarn this wouldn’t be the case, but in npm we do need to write those, if we’re passing some arguments to the npm script that we wrote…

Command for Production

"build": "npm run clean && npm run compile && npm run prefix && npm run minify"

And we are officially done!

Our package.json file should now contain context from below, excluding the boilerplate that we generated with our initial npm command…

P.S. Do not remove that boilerplate…

Now we can use any of those npm scripts that we just wrote for our dummy-project and achieve what we initially required. Write some Sass in our empty file to test it out…

  1. npm run dev — To begin with development, it will watch for changes and re-compile accordingly
  2. npm run build — To get it ready for production. It will clean the dist directory, compile your Sass to CSS, run it through autoprefixer to add any vendor prefixes required and finally run it through minify to create an additional minified file.

Until next time

Originally written on my Medium

Discover and read more posts from Nenad Novaković
get started
post commentsBe the first to share your opinion
Show more replies