Where to Discuss?

Preface

Goal: Bundle HTML + Stylus + Coffeescript together, using rollup.

We have already discussed a webpack example, targeting modern web development. Why not go further with another bundler? Such as rollup.

Source Examples

You can obtain source examples here:


Example: In a Nutshell

Rollup is also a bundler.

How does it looks like?

Supposed that you have these source assets:

└── src
    ├── css
    │   └── style.styl
    ├── entry.js
    ├── html
    │   └── alert.html
    └── js
        └── script.coffee

All the sources, including html, stylus, and coffeescript, will be bundled into one bundle.js, a stylesheet and one index.html.

└── build
    ├── index.html
    └── js
       └── bundle.js

Very similar with webpack. It means, the stylesheet can also be included, as a part of javascript script.js, or be exported to external .css file.

I hope this explains 🙏🏽.

Official Documentation

You should read this first.

This article is useless if you never touch the official documentation.

Difference

In my personal experience webpack config is longer, but more stable with standarized plugin. On the other hand, rollup configuration is shorter. These rollup plugin are third plugin, and unfortunately they are not always working. You need some trial and error.

Learn by Example

This article use previous example, converted to rollup configuration, explained step by step.


1: Preparation

For each step, we are going to need these

  1. package.json, and

  2. rollup.config.js

  3. Assets in respective directory, such as js, css and so on.

  4. Output directory, in this example is build.

package.json

All you need to know is each step has different devDependencies.

  "devDependencies": {
    "rollup": "^2.9.0"
  }

To begin with each step, you need to run npm install first.

Directory Tree

Our preparation example only have to files.

  • src/js/script.js with the same content with our previous article.

  • build/js/script.js generated by rollup later. You can remove build/* anytime.

├── build
│   └── js
│       └── script.js
├── package.json
├── rollup.config.js
└── src
    └── js
        └── script.js

Webpack: Prepare: Directory Tree

Example Javascript

Th example src/js/script.js contain this file:

document.addEventListener("DOMContentLoaded", function(event) { 
  var alertButtons = document.getElementsByClassName("dismissable");
    
  for (var i=0; i < alertButtons.length; i++) {
    alertButtons[i].onclick = function() {
      this.parentElement.style.display='none';
      console.log('Close Button. Element ' + this.parentElement.id + ' dismissed');
      return false;
    };
  };
});

rollup.config.js

A typical configuration is shown as below.

export default {
  input: [ 
    'src/js/script.js'
  ],
  output: { 
    file: 'build/js/script.js',
    format: 'iife'
  }
}

Now you can run rollup in your favorite terminal.

❯ rollup -c -w
rollup v2.9.0
bundles src/js/script.js → build/js/script.js...
created build/js/script.js in 30ms

[2020-05-12 00:46:21] waiting for changes...

Unlike webpack, the output is not so verbose.

Rollup: Prepare: Running Rollpack in Terminal with Watch

Result

As you can see, the rollup generate build/js/script.js, that contain exact script from src/js/script.js, with additional lines.

(function () {
  'use strict';

  ...

}());

I think that’s enough about preparation.

Entry Point in Configuration

Just this.

  input: [ 
    'src/js/script.js'
  ],

2: Assets - Stylesheet

Depend on plugin you use, you can either embed stylesheet, or output stylesheet to external files. The plugin choice decision is depend on your requirement.

Consider start with output to external style example.

Objective

Generate output from the src/css/style.css stylesheet into build/css/style.css

Directory Tree

Additional artefact: src/css/style.css.

├── build
│   ├── css
│   │   └── style.css
│   └── js
│       └── script.js
├── package.json
├── rollup.config.js
└── src
    ├── css
    │   └── style.css
    ├── entry.js
    └── js
        ├── live.js
        └── script.js

Remember that we still does not have any HTML artefact. So nothing to be shown in the browser yet. You can still examine the result using text editor.

Example Stylesheet

Th example src/css/style.js contain this file:

...
.red {
  color: #fff !important;
  background-color: #f44336 !important;
}
.yellow {
  color: #000 !important;
  background-color: #ffeb3b !important;
}
...

package.json

Additional rollup plugin rollup-plugin-css-only.

rollup.config.js

The configuration has only one entry point: the src/entry.js.

import css from 'rollup-plugin-css-only';

export default {
  input: 'src/entry.js',
  output: { 
    file: 'build/js/script.js',
    format: 'iife'
  },
  plugins: [
    css({ 
      output: 'build/css/style.css' 
    })
  ]
}

entry.js

To make life easier, I make a file named entry,js, with content as below code:

import './js/script.js'
import './css/style.css'

You can name the file anything you like, as long as it is javascript.

The rollup-plugin-css-only enable the javacript, to understand the css file format to be imported.

Command Line Interface

Just run the rollup in terminal

rollup v2.9.0
bundles src/entry.js → build/js/script.js...
created build/js/script.js in 36ms

[2020-05-12 01:15:05] waiting for changes..

Rollup: Stylesheet: Running Rollpack in Terminal with Watch

Result

As you can see, the rollup generate build/css/style.css, that contain exact stylesheet from src/css/style.css.

Entry Point in Configuration

I use entry point as below

    input: 'src/entry.js',

Instead of this

  input: [ 
    'src/js/script.js'
  ],

Plugin in Configuration

Based on rollup-plugin-css-only.

    css({ 
      output: 'build/css/style.css' 
    })

3: Template - HTML

There are some plugin to for use with HTML in rollup. One plugin equipped injected assets, one other can place the output to the right folder, and the other plugin has different feature. The choice is your.

Objective

Generate build/index.html, from src/html/index.html.

Directory Tree

Additional artefact: src/html/alert.html.

├── build
│   ├── css
│   │   └── style.css
│   ├── index.html
│   └── js
│       └── script.js
├── package.json
├── rollup.config.js
└── src
    ├── css
    │   └── style.css
    ├── entry.js
    ├── html
    │   └── alert.html
    └── js
        └── script.js

Example HTML Document

Th example src/html/alert.html contain this file:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Example Template</title>
    <link href="css/style.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div class="container">
      ...
    </div>
  </body>
</html>

Notice this two:

  • Hardcoded css/style.css, because the plugin I choose does not inject stylesheet.

  • Nothing said about js/script.js. This will be injected.

You can use other plugin to inject stylesheet.

package.json

Additional rollup plugin rollup-plugin-generate-html-template.

rollup.config.js

The configuration has only one entry point: the src/entry.js.

import html from 'rollup-plugin-generate-html-template';
import css from 'rollup-plugin-css-only';

export default {
  input: 'src/entry.js',
  output: { 
    file: 'build/js/script.js',
    format: 'iife'
  },
  plugins: [
    css({ 
      output: 'build/css/style.css' 
    }),
    html({
      template: 'src/html/alert.html',
      target: 'build/index.html',
      inject: 'head',
      externals: [
        { type: 'js', file: "js/script.js", pos: 'before' }
      ]
    })
  ]
}

Command Line Interface

Just run the rollup in terminal

rollup v2.9.0
bundles src/entry.js → build/js/script.js...
created build/js/script.js in 40ms

[2020-05-12 01:46:03] waiting for changes...

View in Browser

Run your browsersync or just open the build/index.html from file manager. You will see something similar like this below:

Rollup: Bundle: Open index.html in Browser

Result

As you can see, the rollup generate build/index.html, that contain exact html page document from src/html/alert.html, with js/script.js injected at the bottom page.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Example Template</title>
    <link href="css/style.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div class="container">
      ...
    </div>
  <script  src="js/script.js"></script>
</body>
</html>

Plugin in Configuration

Based on rollup-plugin-generate-html-template.

    html({
      template: 'src/html/alert.html',
      target: 'build/index.html',
      inject: 'head',
      externals: [
        { type: 'js', file: "js/script.js", pos: 'before' },
      ]
    })

Note that this won’t work:

      externals: [
        { type: 'js', file: "js/script.js", pos: 'before' },
        { type: 'css', file: "css/style.css", pos: 'before' }
      ]

4: Assets - Copy

We do not need live.js as rollup can utilize livereload perfectly, and also rollup has its own server plugin. But I just need to show an example, that sometime we need to copy assets directly from src to build.

Objective

Copy the src/js/live.js stylesheet into build/js/live.js.

Directory Tree

Additional artefact: src/js/live.js.

├── build
│   ├── css
│   │   └── style.css
│   ├── index.html
│   └── js
│       ├── live.js
│       └── script.js
├── package.json
├── rollup.config.js
└── src
    ├── css
    │   └── style.css
    ├── entry.js
    ├── html
    │   └── alert.html
    └── js
        ├── live.js
        └── script.js

package.json

Additional rollup plugin rollup-plugin-copy.

rollup.config.js

The configuration has only one entry point: the src/entry.js.

import html from 'rollup-plugin-generate-html-template';
import css from 'rollup-plugin-css-only';
import copy from 'rollup-plugin-copy'

export default {
  input: 'src/entry.js',
  output: { 
    file: 'build/js/script.js',
    format: 'iife'
  },
  plugins: [
    css({ 
      output: 'build/css/style.css' 
    }),
    html({
      template: 'src/html/alert.html',
      target: 'build/index.html',
      inject: 'head',
      externals: [
        { type: 'js', file: "js/script.js", pos: 'before' }
      ]
    }),
    copy({
      targets: [
        { src: 'src/js/live.js', dest: 'build/js' },
      ]
    })
  ]
}

Command Line Interface

Just run the rollup in terminal

rollup v2.9.0
bundles src/entry.js → build/js/script.js...
created build/js/script.js in 121ms

[2020-05-12 02:21:48] waiting for changes...

Still the very same output.

Result

Just a copy of file: build/js/live.js.

We do not need this example live.js, as we are going to use livereload later.

Plugin in Configuration

Based on rollup-plugin-copy.

    copy({
      targets: [
        { src: 'src/js/live.js', dest: 'build/js' },
      ]
    })

What’s Next?

Consider continue reading [ Bundler - Rollup - Part Two ].