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:
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 a
src
directory for development - In our
src
directory, we will make a file calleddummy.scss
, which will contain our Sass code with Scss syntax - We will have a
dist
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 usingyarn
this wouldn’t be the case, but innpm
we do need to write those, if we’re passing some arguments to thenpm 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…
npm run dev
— To begin with development, it will watch for changes and re-compile accordinglynpm run build
— To get it ready for production. It willclean
thedist
directory,compile
your Sass to CSS, run it throughautoprefixer
to add any vendor prefixes required and finally run it throughminify
to create an additional minified file.