In this series, I'll take a look on a simple usecase of js+html application, build with various js bundlers. In earlier articles, we've seen how far we can get without any bundler and how it goes wepback & esbuild. Here we will take look on rollup.js.
Rollup 2
Rollup seems to be in an interesting point - on many metrics just after webpack - second most popular, second oldest:
but in the same time, seems it's not generating as much excitement as some newer tools - like discussed previously esbuild. But it's still worth taking a look - just because of it's popularity, you can come across it in some project.
The app
same as other articles of this series, simple app with 1 component with template & data in separate files.
Code
The main html file is simple:
<!-- index.html -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Contact App</title>
<link rel="shortcut icon" href="#" />
<script type="module" src="./dist/index.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body></body>
</html>
the source file, ./dist/index.js
has to be match to what we set as output in rollup.config.js
.
Main js file:
// src/index.js
import "./contact-list/contact-list";
no surprise here, rollup behaves in the same way we are already accustomed by other bundlers.
The component
The component is broken down into 3 files. By default, rollup supports JS files only. For JSON & HTML, we will need to install a plugin & set up configuration.
// src/contact-list/contact-list.js
import template from "./contact-list.html";
import contacts from "./data.json";
const contactList = document.createElement("div");
contactList.className = "contact-list";
contacts.forEach((entry) => {
const element = document.createElement("div");
element.className = "contact";
element.innerHTML = template;
element.querySelector(".name").innerHTML = entry.name;
element.querySelector(".phone").innerHTML = entry.phone;
contactList.appendChild(element);
});
document.body.appendChild(contactList);
So far, each bundler works with the same application code - that's very good for migrations if we ever decide going from building with one tool to some other.
Even for JSON files, rollup needs an aditional library - a json plugin. The installation & configuration will be covered below.
src/contact-list/data.json
, the data file:
[
{
"name": "Christopher L Sanders",
"phone": "769-232-1807"
},
{
"name": "Frances J Nolte",
"phone": "901-287-0419"
}
]
HTML files, where the source of the biggest confusion for me. Looks that I'm very used to webpack's html-loader
, and it's way of thinking. The rollup's core html plugin seems to do slightly different thing. In the end I got my template as a string into js by a combination of @rollup/plugin-babel
& babel's plugin babel-plugin-transform-html-import-to-string
. This solution felt pretty over engineered to me - I'm either very off with how I approached the problem, or I was trying to force rollup to behave in a way it would rather not. I guess, in cases when you use reacts' jsx
or tsx
, it feels much smoother, because you don't move template out of js.
<!-- src/contact-list/contact-list.html -->
<h2 class="name">name</h2>
<p class="phone">phone</p>
Build dependencies & configuration
For a successful build of the above code, we need quite a few things. To install them all:
$ npm install --save-dev @babel/preset-env @rollup/plugin-babel @rollup/plugin-json rollup babel-plugin-transform-html-import-to-string
The configuration:
// rollup.config.js
import { babel } from "@rollup/plugin-babel";
import json from "@rollup/plugin-json";
const config = {
input: "src/index.js",
output: {
format: "esm",
file: "dist/index.js",
},
plugins: [
babel({
exclude: "node_modules/**",
presets: ["@babel/preset-env"],
plugins: ["babel-plugin-transform-html-import-to-string"],
extensions: [".js", ".html"],
}),
json(),
],
};
export default config;
That is a bit disappoiting - especially if you heard horror storries about wepback confiuration, here even simple usecase requires a lot of configuration.
For easy access to build script, you can add following line to package.json
:
"scripts": {
// other scripts
"build": "rollup -c rollup.config.js"
}
succesful build:
$ npm run build
> rollup@1.0.0 build
> rollup -c rollup.config.js
src/index.js → dist/index.js...
babelHelpers: 'bundled' option was used by default. It is recommended to configure this option explicitly, read more here: https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers
created dist/index.js in 301ms
Complete code & application example
If you want to see the application in action in the browser you can see it here:
https://marcin-wosinek.github.io/js-html-comparison-rollup-2/
and for the working code example you can go here:
https://github.com/marcin-wosinek/js-html-comparison-rollup-2
Top comments (0)