Javascript module bundler: rollup.js (Essential to learn)
Here we will learn how to use rollup.js in UI application
📚What is rollup.js?
- Rollup.js is a module bundler for Javascript applications.
- It allows developers to bundle their code into a single or multiple file/s. Making it easier to manage dependencies and improve performance.
- It’s commonly used on front-end development for building applications, libries and plugins.
📚How to create a web project with RollupJs📚
1. Create a basic environment:
- Create Project Directory
mkdir rollupjs && cd rollupjs
- install package.json
npm init -y
2. Add rollup dependencies into the project
- Difference between dependencies & dev-dependencies in Node.js:
- Dependencies are the packages that your project needs to run properly in production.
- Dev-dependencies are the packages that are needed for development and building the project, but not required for it to run in production. - install Rollup as a global command line tool:
npm install --global rollup
- install dependencies:
rollup
npm i rollup --save-dev
So, in your package.json it’s added like:
"dependencies": {
"rollup": "^4.6.1"
},
- change script in
package.json
to build the project
"scripts": {
// need some specific format describe later
"build": "rollup"
},
3. Create project structure for rollupjs
- Application basic structure:
rollupjs
│
├───build
│ ├───index.html
│ └───bundle.js (auto create after build)
│
├───node_modules
│
├───src
| └───index.js
|
├───package-lock.json
└───package.json
- Create two directories:
build
&src
- Create
index.html
withinbuild
repo.
<!DOCTYPE html>
<html lang="eng">
<head>
<title>rollup</title>
</head>
<body>
<div style="text-align:center" id="main"></div>
<script src="bundle.js"></script>
</body>
</html>
- Create
index.js
undersrc
repo.
function mainContaint() {
var el = document.createElement("h1");
el.textContent = "This is First Rollup Project";
return el;
}
document.getElementById("main").appendChild(mainContaint());
- Now run the project:
npm run build
- After run above script, it will openrollup --help
page. Where clearly declear some specific format to build the code as follows:
- So, to build the project required some format as
input_source_path
,output_dir_path
,build_format
.
- Rollup support build formatamd
,cjs
,system
,es
,iife
orumd
.
- Here input file path:src/index.js
- Output directory:build/bundle.js
- Now modifypackage.json
build script as follows:
"scripts": {
// "rollup --format=<format> --file=<output_dir> -- <input_dir>
"build": "rollup --format=cjs --file=build/bundle.js -- src/index.js"
},
------- OR -------
"scripts": {
// "rollup <input_dir> --file <output_dir> --format <format>
"build": "rollup ./src/index.js --file ./build/bundle.js --format cjs"
},
- So, RollupJs build the default script
src/index.js
& store build files underbuild
folder name as:bundle.js
- Now I explain how to add modules.
rollupjs
│
├───build
│ ├───index.html
│ └───bundle.js (auto create after build)
│
├───node_modules
│
├───src
│ ├───index.js
| └───module.js (add a new file)
|
├───package-lock.json
└───package.json
- Now create another file under
src
repo asmodule.js
.We are trying to import something into index.js and let's check what will happen… - Add this code within
module.js
file
export function module() {
var el = document.createElement("h2");
el.textContent = "This is Rollup Module Page";
return el;
}
- Now import
module.js
intoindex.js
file and updateindex.js
as follows:
import { module } from "./module";
function mainBody() {
var el = document.createElement("h1");
el.textContent = "This is First Rollup Project";
return el;
}
function main() {
var d = document.getElementById("main");
d.appendChild(mainBody());
d.appendChild(module());
}
(function () {
main();
})();
- Run the project:
npm run build
- Now you understand how to build your project using RollupJs.
- If you are using visual code then you may run your project with “live-server”. Otherwise, you directly open
build/index.html
file locally and after build refresh the browser. - So, you will add multiple files in this way and create UI according to that.
4. Describe different type of Module Loaders
Module loader is a mechanism or software concept that facilitates the loading, resolution and execution of modular code in programming environent.
In the context of web development and JavaScript, module loader are essential for managing modular code organization and handling dependencies between different parts of an application.
AMD (Asynchronous Module Definition):
This format allows modules to be define asynchronously. It’s commonly used in browsers for managing dependencies and loading modules.CJS (Common JS):
Generally used in serverside, like Node.js. Defines a synchronous approach to loading modules and allows modules to include their dependencies directly.ES/ESM (ESMAScript):
This module introduced the ES6 features likeimport
,export
statements.IIFE (Immediately Invoken Function Expression):
A Javascript design pattern whire function is defined and eecuted immediately after its creation. Help to create private scope for variable to avoid pooluting the global scope.SYSTEM/SYSTEMJS:
It introduce it’s own module format called “System.register”, which includeds metadata from module dependencies and allow for lazy loading. That can work with various format including CommonJS, AMD & ES6.UMC (Universal Module Definition):
This pattern allow a javascript library to work in various module system, including AMD, CommonJS and as a global variable. A versatile approach that enables developers to use a library in different environents.
📚RollUp configuration & Basic Plugins📚
1. Setup Basic Rollup Configuratin file:
Now package.json script as follows:
"scripts": {
"build": "rollup ./src/index.js --file ./build/bundle.js --format cjs"
},
- Let’s create a rollup configuration file:
rollup.config.js
- Update
package.json
script config inrollup.config.js
as follows:
// rollup.config.js
module.exports = [{
input: './src/index.js',
output: {
file: './build/bundle.js',
format: 'cjs'
}
}];
- Now, update
package.json
script as follows
"scripts": {
"build": "rollup --config"
},
-------- OR --------
"scripts": {
"build": "rollup --config rollup.config.js"
},
- After build the code, output file (
build/bundle.js
) show as:
2. Setup Rollup in watch mode
Rollup has a watch mode that allows it to watch any changes in our source files and automatically rebuild the project when changes are detected.
To use the watch mode, you can use the -w
or --watch
flag when running the Rollup command.
So, need to upgrade package.json
script
as follows:
"scripts": {
"build": "rollup --config --watch"
},
-------- OR --------
"scripts": {
"build": "rollup --config rollup.config.js --watch"
},
-------- OR --------
"scripts": {
"build": "rollup -c rollup.config.js -w"
},
3. Setup Rollup Plugin for Live Server
Still now we are using either vs-code live-server or run it locally.
In this block, we will learn how to create a rollup plugin to serve the bundle.
- Install Rollup Plugin for Live Server:
Live server — rollup-plugin-server:npm install --save-dev rollup-plugin-serve
Automatic reload — rollup-plugin-livereload:npm install — save-dev rollup-plugin-livereload
- So,
package.json
added the bothdevDependencies
as follows:
// pacakge.json
... ... ...
"devDependencies": {
"rollup": "^4.6.1",
"rollup-plugin-livereload": "^2.0.5",
"rollup-plugin-serve": "^3.0.0"
}
... ... ...
- Let configure
rollup-plugin-serve
&rollup-plugin-livereload
plugins inrollup.config.js
as follows:
// rollup.config.js
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
export default [{
input: 'src/index.js',
output: {
file: 'build/bundle.js',
format: 'es'
},
plugins: [
serve({
// Launch in browser (default: false)
open: true,
// Page to navigate to when opening the browser.
openPage: '/index.html',
// Folder to serve files from
contentBase: 'build',
// Options used in setting up server
host: 'localhost',
port: 8008,
}),
// Automatic page refresh after any changes
livereload('build')
]
}];
- Now build the code throgh
pacakge.json
—npm run build
- Now live server will work and show as follows:
4. Setup Rollup Plugin to Copy HTML file
Still now we are using index.html
under the build
directory.
Lets create a different directory for index.html
, public
. Also add the module.js
under src
and update index.js
accordingly.
So, project structure as follows:
rollupjs
│
├───build
│ ├───index.html (buildFile: HTMLPlugin)
│ └───bundle.js (buildFile: auto create after build)
│
├───public (new directory for `index.html`)
│ └───index.html
│
├───src
│ ├───index.js
| └───module.js
|
├───package-lock.json
├───package.json
|
└───rollup.config.js
Clarly required some HtmlPlugin in rollup.config.js
and after build two files will create under build directory; index.html
& bundle.js
.
- Install Rollup Plugin to copy HTML file:
rollup-plugin-copy :npm install — save-dev rollup-plugin-copy
- Configure plugin in
rollup.config.js
:
// rollup.config.js
... ... ...
import copy from 'rollup-plugin-copy';
export default [{
... ... ...
plugins: [
copy({
targets: [{
// Copy HTML files from src to build
src: 'public/index.html',
dest: 'build'
}],
}),
... ... ...
... ... ...
]
}];
- Now build the code:
npm run build
📌 Check details about Rollup Configuratin Files:👉 link
📚RollUp configuration: CSS & Style Loader📚
Now we will add images
and css
files in this project.
So, we need to add css plugins.
- Add Rollup css plugin — rollup-plugin-css-only :
npm install --save-dev rollup-plugin-css-only
- Lets update our project structure & then we will configure the css plugin in rollup config.
rollupjs
│
├───build (build repo)
│
├───public
│ └───index.html
│
├───src
│ ├───images (contains all type of images)
│ │
│ ├───module
│ │ ├───module.css
│ │ └───module.js
│ │
│ ├───index.css
| └───index.js
|
├───package-lock.json
├───package.json
|
└───rollup.config.js
Need to remember:
— — Need to create css
file with same .js
file name.
— — If you create some module and every module have separate css, then also create css with same module name and both *.js
& *.css
will in same directory.
— — If you create a single css along the project, then it should be index.css
and it will exist same directory, where index.html
is exist.
— — For image file/s created a separate directory, images
.
- Now update
module.js
,module.css
,index.js
&index.css
as follows:
// index.css
body {
background-color: aqua;
background-image: url('./images/bg.avif');
}
.cl1 {
color: red;
font-size: 100px;
}
===========================================================
// index.js
import { module } from "./module/module";
import './index.css';
function mainBody() {
var el = document.createElement("h1");
el.textContent = "This is First Rollup Project";
return el;
}
function main() {
var d = document.getElementById("main");
d.appendChild(mainBody());
d.appendChild(module());
}
(function () {
main();
})();
// module.css
.cl2 {
color: pink;
font-size: 60px;
}
#my_logo {
content: url('./images/logo.png');
width: 200px;
height: 200px;
padding: 20px;
background-color: white;
}
===========================================================
// module.js
import './module.css';
function addImage() {
var x = document.createElement("img");
x.id = "my_logo";
var el = document.createElement("div");
el.appendChild(x);
return el;
}
export function module() {
var el = document.createElement("h2");
el.className = "cl2";
el.id = "id2";
el.textContent = "This is Module Page";
el.appendChild(addImage());
return el;
}
- What we will do in css plugin config ?
— — bundleall css
across project to asingle css
file and it should be store inbuild
dirctory.
— — copy all image files (src/images/*
) tobuild
directory. - So, css plugin configuration in
rollup.config.js
as follows:
// rollup.config.js
... ... ...
import css from 'rollup-plugin-css-only'
export default [{
input: 'src/index.js',
output: {
file: 'build/bundle.js',
format: 'cjs'
},
plugins: [
css({
// all `*.css` files in src directory
input: ['src/*.css', 'src/*/*.css'],
// Optional: filename to write all styles to
output: 'bundle.css'
}),
copy({
targets: [{
// Copy HTML files from public to build
src: ['public/*'],
dest: 'build'
}, {
// Copy images from src to build
src: ['src/images/*'],
dest: 'build/images'
}],
}),
serve({
/* existing code */
});
livereload('build')
]
}];
- Now build the code through pacakge.json:
npm run build
📚Important Rollup Plugins📚
- Module Resolution:
Plugins like@rollup/plugin-node-resolve
help resolve module paths, especially for dependencies installed in thenode_modules
directory. This is essential for Rollup to locate and bundle external modules. - CommonJS to ES Module Conversion:
Many third-party packages are written in CommonJS format. The@rollup/plugin-commonjs
plugin converts CommonJS modules to ES modules, making them compatible with Rollup's module system. - Code Transformation:
Plugins likerollup-plugin-babel
,rollup-plugin-typescript
, or@rollup/plugin-terser
enable the transformation of code written in different languages (e.g., ES6/ESNext, TypeScript) and perform tasks like transpilation and minification. - CSS and Stylesheet Handling:
Plugins likerollup-plugin-postcss
allow Rollup to process and bundle CSS files, and optionally extract them into separate files. This is essential for managing styles in modern web development. - HTML and Asset Management:
While Rollup primarily focuses on JavaScript, plugins likerollup-plugin-html
orrollup-plugin-copy
assist in handling HTML files and other assets, ensuring a comprehensive build process. - Live Development Server:
Plugins such asrollup-plugin-serve
androllup-plugin-livereload
provide features for local development, allowing you to serve your application, automatically reload pages, and debug more efficiently during development. - Tree Shaking:
Rollup is known for its tree-shaking capabilities, eliminating dead code to generate smaller bundles. Plugins likerollup-plugin-node-builtins
androllup-plugin-node-globals
help with tree shaking by providing necessary polyfills. - Dynamic Import Handling:
Plugins like@rollup/plugin-dynamic-import-vars
and@rollup/plugin-dynamic-import
assist in handling dynamic imports, a feature introduced in ECMAScript modules. - Customization and Extensibility:
Rollup plugins provide a way to extend Rollup’s behavior according to project-specific requirements. This customization is essential for handling diverse project structures, external dependencies, and specific build optimizations. - Optimizations and Minification:
Plugins like@rollup/plugin-terser
orrollup-plugin-uglify
help minify and optimize the final bundled JavaScript code, reducing its size for production deployment.
📌 Check different type of rollup plugins details: 👉 link
📚Rollup Configuration Mode: dev or prod📚
1. What are dev & prod
mod ?
— Production Mode:
Primarily intended for use during the development and testing phases of a software project.
— Development Mode:
Designed for the final deployment of an application in a live or production environment, where performance and efficiency are critical.
✅Rollup devServer (rollup-plugin-serve
& rollup-plugin-livereload
) & watch mode (-w
) not required for production mode.
✅Production mode used JavaScript minifier and mangler (@rollup/plugin-terser
) that can help reduce the size of your JavaScript files.
✅Production mode will use Javascript Obfuscator (rollup-obfuscator
) to difficult to understand or reverse engineer our existing code.
🇳🇧✍️I will change
rollup.config.js
buildle files as follows:
✔ js bundle file:bundle.js
➡sript.js
✔ css bundle file name:bundle.css
➡style.css
Please updaterollup.config.js
&*.html
files accordingly
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
There are two way to create dev & prod mode rollup.js build.
1️⃣ ThroughPacakge.json
we set dev & prod mode build.
2️⃣ We will set two diffentrollup.config
for dev & prod mode and set up accordingly.
2. Config Rollup dev & prod build mode through package.json
- Update package.json script for prod & dev build as follows :
"scripts": {
"build:prod": "NODE_ENV=production rollup -c rollup.config.js",
"build:dev": "rollup -c rollup.config.js -w"
},
- We will create two different directory under
build
directory, name asprod
&dev
for production & development build respictively.
Also use JavaScript minifier (@rollup/plugin-terser
plugin) for prduction build and not used rollup-server for production build. - Now, update rollup.config.js as follows for prod & dev mode:
// rollup.config.js
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
import copy from 'rollup-plugin-copy';
import css from 'rollup-plugin-css-only';
// Used for production build
import terser from '@rollup/plugin-terser';
const isProductionBuild = process.env.NODE_ENV === 'production';
console.log('is Rollup Production Build: ', isProductionBuild ? "Yes" : "No");
export default [{
input: 'src/index.js',
output: {
file: `build/${isProductionBuild ? 'prod' : 'dev'}/script.js`,
format: 'cjs'
},
plugins: [
css({
// all `*.css` files in src directory
input: ['src/*.css', 'src/*/*.css'],
// Optional: filename to write all styles to
output: 'style.css'
}),
copy({
targets: [{
// Copy HTML files from public to build
src: ['public/*'],
dest: `build/${isProductionBuild ? 'prod' : 'dev'}`
}, {
// Copy images from src to build
src: ['src/images/*'],
dest: `build/${isProductionBuild ? 'prod' : 'dev'}/images`
}],
}),
!isProductionBuild && serve({
// Launch in browser (default: false)
open: true,
// Page to navigate to when opening the browser.
openPage: '/index.html',
// Folder to serve files from
contentBase: `build/${isProductionBuild ? 'prod' : 'dev'}`,
// Options used in setting up server
host: 'localhost',
port: 8008,
}),
// Automatic page reload after any changes
!isProductionBuild && livereload(`build/${isProductionBuild ? 'prod' : 'dev'}`),
// JavaScript minifier
isProductionBuild && terser({
maxWorkers: 4,
compress: {
drop_console: true,
}
}),
]
}];
3. Config Rollup dev & prod mode build with different file
- Create two files
rollup.config.dev.js
&rollup.config.prod.js
and copy exising code ofrollup.config.js
to both file. - We will create two different directory under
build
directory, name asprod
&dev
for production & development build respictively. - Create
dev
&prod
build script inpackage.json
and usewatch
mode only fordev
build.
So, changes as follows:
// package.json
"scripts": {
"build:prod": "rollup -c rollup.config.prod.js",
"build:dev": "rollup -c rollup.config.dev.js -w",
}
- 💥💥💥Create Rollup Devlopment Config💥💥💥
Now update rollup dev config according tobuild/dev
directory.
So,rollup.config.dev.js
changes as follows:
// rollup.config.dev.js
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
import copy from 'rollup-plugin-copy';
import css from 'rollup-plugin-css-only';
export default [{
input: 'src/index.js',
output: {
file: 'build/dev/script.js',
format: 'cjs'
},
plugins: [
css({
// all `*.css` files in src directory
input: ['src/*.css', 'src/*/*.css'],
// Optional: filename to write all styles to
output: 'style.css'
}),
copy({
targets: [{
// Copy HTML files from public to build
src: ['public/*'],
dest: 'build/dev'
}, {
// Copy images from src to build
src: ['src/images/*'],
dest: 'build/dev/images'
}],
}),
serve({
// Launch in browser (default: false)
open: true,
// Page to navigate to when opening the browser.
openPage: '/index.html',
// Folder to serve files from
contentBase: 'build/dev',
// Options used in setting up server
host: 'localhost',
port: 8008,
}),
// Automatic page reload after any changes
livereload('build/dev')
]
}];
- 💥💥💥Create Rollup Production Config💥💥💥
Now update rollup prod config according tobuild/dev
directory.
— Remove Rollup Plugin Live Server (rollup-plugin-serve
&rollup-plugin-livereload
) config.
— Add JavaScript minifier plugin(@rollup/plugin-terser
) for prduction build, for Reduced File Size, Improved Page Load Performance, Caching Efficiency, Tree Shaking.
— Add JavaScript obfuscator plugin(rollup-obfuscator
/javascript-obfuscator
) for prduction build, which Code Protection, Security Through Obscurity, String and Code Encryption, Reduced Risk of Code Tampering, Compliance with Licensing Agreements etc.
So,rollup.config.dev.js
changes as follows:
// rollup.config.prod.js
import copy from 'rollup-plugin-copy';
import css from 'rollup-plugin-css-only'
import terser from '@rollup/plugin-terser';
import { obfuscator } from 'rollup-obfuscator';
export default [{
input: 'src/index.js',
output: {
file: 'build/prod/script.js',
format: 'cjs',
name: 'production'
},
logLevel: 'none',
plugins: [
css({
// all `*.css` files in src directory
input: ['src/*.css', 'src/*/*.css'],
// Optional: filename to write all styles to
output: 'style.css'
}),
copy({
targets: [{
// Copy HTML files from public to build
src: ['public/*'],
dest: 'build/prod'
}, {
// Copy images from src to build
src: ['src/images/*'],
dest: 'build/prod/images'
}],
}),
terser({ // JavaScript minifier
// maximum number of worker processes for parallelizing the minification process
maxWorkers: 4,
compress: {
// Remove console.log statements in production build
drop_console: true,
}
}),
obfuscator({
// what files will obfuscate or what not
include: ['src/**/*.js', 'public/*.html'],
exclude: ['node_modules/**'],
// Obfuscator Rules
compact: false,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
numbersToExpressions: true,
simplify: true,
stringArrayShuffle: true,
splitStrings: true,
stringArrayThreshold: 1
})
]
}];
- How to build dev & prod build:
— — Production build:npm run build:prod
: will create a obfuscate minifire library
— — Development Build:npm run build:dev
: will create a common js library for devepment testing. - More details check rollup documentation
- check sample code👉 Rollupjs_sample-code