You might not need a build tool

It’s good to know about the “native” way

npm is more powerful you’d expect (image from: https://www.npmjs.com)

Build tools come in all size and color. But do you really need them? Wouldn’t it be easier to just follow the original CLI documentation of Rollup, Stylus or whatever and call it a day? Not to mention they add up a lot of dependencies.

I’m going to show you the “native” way with NPM scripts and chokidar.

Initialize node.js project

Let’s start by creating a node.js project. Open your terminal and write:

$ mkdir example

$ cd example

$ npm init -y

Also create some folders and install express:

$ mkdir -p css js public/js public/css

$ npm i express --save

Then we need a simple web server, create and open server.js in the editor:

const path = require('path');

const express = require('express'); const app = express();

const PUBLIC = path.join(__dirname, 'public'); app.use(express.static(PUBLIC)); app.listen(8080);

Create some NPM scripts

Next we’ll install JS and CSS tools. If you like, you can replace with your weapon of choice.

$ npm i stylus nib rollup rollup-plugin-buble uglify-js --save-dev

Then let’s add some npm scripts. The beauty about npm scripts is that all your dependencies are installed locally and you can use original documentation to run commands. Open package.json in your editor and add following lines:

{

"name": "example",

"version": "1.0.0",

"description": "",

"main": "index.js",

"scripts": {

"dev": "node watch", "build-css": "stylus -u nib css/index.styl -o public/css/main.css", "build-js": "rollup -c -f iife js/index.js -o public/js/main.js", "uglify-js": "uglifyjs public/js/main.js -cmo public/js/main.min.js"

},

"keywords": [],

"author": "",

"license": "ISC"

}

Let’s dive into details:

stylus -u nib css/index.styl -o public/css/main.css

Run stylus

Load nib plugin

Read from css/index.styl

Write to public/css/main.css

rollup -c -f iife js/index.js -o public/js/main.js

Run rollup

Use configuration file (we’ll create that in a second)

Format to IIFE

Read from js/index.js

Write to public/js/main.js

uglifyjs public/js/main.js -cmo public/js/main.min.js

Run uglify-js

Read from public/js/main.js

Compress & minify

Write to public/js/main.min.js

Configure Rollup

Next we’ll create the rollup configuration file. Create and open rollup.config.js in your editor:

import buble from 'rollup-plugin-buble'; export default {

plugins: [

buble()

]

};

That’s it.

Create a file watcher

One more thing. We’ll need a file watcher. Let’s install chokidar:

$ npm i chokidar --save-dev

Then we’ll create watch.js. Paste following lines in your editor:

require('./server'); // run the server const cp = require('child_process');

const chokidar = require('chokidar'); run('build-css');

run('build-js'); chokidar.watch('css/**/*.styl')

.on('change', path => run('build-css')); chokidar.watch('js/**/*.js')

.on('change', path => run('build-js')); chokidar.watch('public/js/main.js')

.on('change', path => run('uglify-js')); function run (scriptName) {

cp.spawn('npm', ['run', scriptName], { stdio: 'inherit' });

}

That’s it! What’s happening there:

Run the server

Load node.js native child_process package

Load chokidar

Run npm run build-css

Run npm run build-js

Start to watch css/**/*.styl and npm run build-css for any changes

Start to watch js/**/*.js and npm run build-js for any changes

Start to watch public/js/main.js and npm run uglify-js for any changes

Define a simple run script for running npm scripts and piping stdout/stderr to watch process

We’ll need some content

Oh, we need some content as well. So we’ll add some CSS. Create and open css/index.styl in your editor:

@import 'nib'; body {

font-family: sans-serif;

}

..and js/index.js:

Not much happening here, either:

const hello = document.createElement('h1'); hello.textContent = 'Hello world!'; document.body.appendChild(hello);

We’ll also need HTML (public/index.html):

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<link rel="stylesheet" href="css/main.css">

</head>

<body>

<script src="js/main.js"></script>

</body>

</html>

Done!

Let’s try it:

$ npm run dev

Navigate to http://localhost:8080

That’s all, folks!

ps. If you want to bootstrap projects easier and like my RE:DOM view library, you can use redom-cli to automate all this + install RE:DOM 😉