{"id":10260,"date":"2025-11-04T18:39:59","date_gmt":"2025-11-04T18:39:59","guid":{"rendered":"https:\/\/hellonitish.com\/blog\/?p=10260"},"modified":"2025-11-05T07:24:35","modified_gmt":"2025-11-05T07:24:35","slug":"understanding-rollup-js-beginners-guide","status":"publish","type":"post","link":"https:\/\/hellonitish.com\/blog\/understanding-rollup-js-beginners-guide\/","title":{"rendered":"Understanding Rollup.js: A Beginner&#8217;s Guide"},"content":{"rendered":"\n<p>Peek inside a modern JavaScript project and you will probably see a folder called <code>dist<\/code> with some massive files inside it with names like colorful.min.js, colorful.esm.js, colorful.umd.js etc. Each of them is meant for a specific target and contain the entire optimized code of your project.<\/p>\n\n\n\n<p>Where did these files come from? A bundler creates them. There are quite a few bundlers that you can use. However, our focus in this post will be on Rollup.<\/p>\n\n\n\n<p>Rollup is a <em>module bundler<\/em>. A quiet but powerful tool that takes all your scattered JavaScript files, follows every <code>import<\/code> trail, removes whatever you\u2019re not using, and rolls it all up into one clean file that browsers can actually understand. It\u2019s the reason your dozens of <code>.js<\/code> files can load as a single, efficient script on the web.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Use a Bundler at All?<\/h2>\n\n\n\n<p>In the early days of the web, you could drop one JavaScript file into your page with a simple line like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script src=\"app.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>That worked fine when your entire project was a few hundred lines of code.<\/p>\n\n\n\n<p>But as apps grew, developers began splitting code into multiple files like <code>math.js<\/code>, <code>utils.js<\/code>, <code>api.js<\/code>, and so on to keep things organized. The browser, however, doesn\u2019t natively understand your project structure. It just sees separate files that it has to fetch one by one.<\/p>\n\n\n\n<p>Each <code>&lt;script&gt;<\/code> tag means a separate network request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script src=\"math.js\"&gt;&lt;\/script&gt;\n&lt;script src=\"utils.js\"&gt;&lt;\/script&gt;\n&lt;script src=\"main.js\"&gt;&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>That&#8217;s three requests for three files.<\/p>\n\n\n\n<p>Now imagine a modern app with <em>hundreds<\/em> of files \u2014 that\u2019s hundreds of separate downloads before your app can even start. Slow, messy, and frustrating.<\/p>\n\n\n\n<p>A <strong>bundler<\/strong> solves this. It takes all those small files, figures out how they depend on each other, and merges them into one or a few optimized files that the browser can load instantly. It also removes unused code (a process called <em>tree-shaking<\/em>), minifies everything, and can even make your modern syntax work on older browsers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How Rollup Works (The Simple Version)<\/h2>\n\n\n\n<p>When you give Rollup an entry file, say <code>src\/colorful.js<\/code>, it starts reading your code. Every time it sees an <code>import<\/code> statement, it follows the trail, pulling in the imported files. It repeats this process recursively until it has your entire project mapped out like a dependency web.<\/p>\n\n\n\n<p>Then, it rolls everything together:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Combines all modules into one file<\/li>\n\n\n\n<li>Removes anything you didn\u2019t use<\/li>\n\n\n\n<li>Produces clean, optimized output files like:<br><code>colorful.esm.js<\/code> (for modern JavaScript) <br><code>colorful.cjs.js<\/code> (for Node.js) <br><code>colorful.umd.js<\/code> (for browsers and AMD) <br><code>colorful.min.js<\/code> (a minified version for production)<\/li>\n<\/ol>\n\n\n\n<p>That\u2019s the \u201croll up\u201d in Rollup \u2014 a bundle of everything you need, nothing you don\u2019t.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Multiple Output Formats Explained<\/h2>\n\n\n\n<p>When you open your <code>dist<\/code> folder after a Rollup build, you might see several files that look suspiciously similar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>colorful.esm.js  \ncolorful.cjs.js  \ncolorful.umd.js  \ncolorful.min.js<\/code><\/pre>\n\n\n\n<p>They all contain the <em>same<\/em> codebase, your project, but each one speaks a slightly different \u201cdialect\u201d of JavaScript. Think of them as the same book translated for different readers.<\/p>\n\n\n\n<p>Let\u2019s break down what each format means.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">ESM \u2014 For the Modern World<\/h3>\n\n\n\n<p>ESM stands for <strong>ES Modules<\/strong>, the official JavaScript module system introduced in ES6 (<code>import<\/code> and <code>export<\/code>).<\/p>\n\n\n\n<p>This format is used by modern browsers and tools like Rollup, Vite, and Webpack.<\/p>\n\n\n\n<p>You can use it like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { getRandomColor } from '.\/colorful.esm.js';<\/code><\/pre>\n\n\n\n<p>Because ESM supports static imports, bundlers can tree-shake it efficiently \u2014 meaning unused parts of your library simply vanish in the final build. This is the <em>most modern and future-proof<\/em> format.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CJS \u2014 The Node.js Veteran<\/h3>\n\n\n\n<p>CJS stands for <strong>CommonJS<\/strong>, the older module system used by Node.js. It uses <code>require()<\/code> and <code>module.exports<\/code> instead of <code>import<\/code> and <code>export<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const { getRandomColor } = require('.\/colorful.cjs.js');<\/code><\/pre>\n\n\n\n<p>This format is mostly for backward compatibility. Older tools, servers, and Node environments still rely on CommonJS. If you\u2019re publishing a library on npm, you\u2019ll definitely want to include this.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">UMD \u2014 The Universal Translator<\/h3>\n\n\n\n<p>UMD stands for <strong>Universal Module Definition<\/strong>, and it\u2019s like a multilingual interpreter. It works everywhere \u2014 Node, AMD (like RequireJS), or directly in the browser.<\/p>\n\n\n\n<p>You can even drop it into an HTML file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script src=\"colorful.umd.js\"&gt;&lt;\/script&gt;\n&lt;script&gt;\n  console.log(Colorful.getRandomColor());\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>It attaches your code to a global variable (in this case, <code>Colorful<\/code>), so browsers without module support can still use it. This makes UMD great for demos, playgrounds, or older environments.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">IIFE \u2014 The Browser-Ready File<\/h3>\n\n\n\n<p>IIFE stands for <strong>Immediately Invoked Function Expression<\/strong>, a self-running script. When loaded, it runs instantly and exposes your library as a global variable.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;script src=\"colorful.min.js\"&gt;&lt;\/script&gt;\n&lt;script&gt;\n  console.log(Colorful.getRandomColor());\n&lt;\/script&gt;<\/code><\/pre>\n\n\n\n<p>The <code>.min.js<\/code> version is the same code, just minified with Terser to make it smaller and faster to load.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">So\u2026 Why So Many?<\/h3>\n\n\n\n<p>Because JavaScript runs in <em>a lot<\/em> of different environments like browsers, servers, build tools, and everything in between.<\/p>\n\n\n\n<p>Rollup makes it easy to build once and ship everywhere.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started with Rollup<\/h2>\n\n\n\n<p>Let&#8217;s start from scratch so you know how Rollup fits in a project.<\/p>\n\n\n\n<p>Execute the following commands in the terminal to create a <strong>math-demo<\/strong> directory and a <strong>package.json<\/strong> file within it.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir math-demo\ncd math-demo\nnpm init -y<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Install Rollup<\/h3>\n\n\n\n<p>Now install Rollup and some of its most common plugins by executing the following command.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm install rollup @rollup\/plugin-node-resolve @rollup\/plugin-commonjs rollup-plugin-terser --save-dev<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>rollup<\/code>: the core bundler<\/li>\n\n\n\n<li><code>node-resolve<\/code>: lets Rollup import packages from <code>node_modules<\/code><\/li>\n\n\n\n<li><code>commonjs<\/code>: converts old-style CommonJS modules into ES modules<\/li>\n\n\n\n<li><code>terser<\/code>: minifies your final output<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Write Some Code<\/h3>\n\n\n\n<p>Now create the <strong>src<\/strong> directory within your project directory, i.e., <strong>math-demo<\/strong>, and create two files named <strong>math.js<\/strong> and <strong>main.js<\/strong> within the <strong>src<\/strong> directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>src\/\n  math.js\n  main.js<\/code><\/pre>\n\n\n\n<p>Add the following code to <strong>math.js<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export function add(a, b) {\n  return a + b;\n}\n\nexport function multiply(a, b) {\n  return a * b;\n}<\/code><\/pre>\n\n\n\n<p>Add the following code to <strong>main.js<\/strong>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { add } from '.\/math.js';\n\nconsole.log('2 + 3 =', add(2, 3));<\/code><\/pre>\n\n\n\n<p>You now have a mini \u201cproject\u201d with one file importing another. This is perfect for testing a bundler.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create a Rollup Config<\/h3>\n\n\n\n<p>Add a file named <strong>rollup.config.js<\/strong> in your root folder, i.e., <strong>math-demo<\/strong> with the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { nodeResolve } from '@rollup\/plugin-node-resolve';\nimport commonjs from '@rollup\/plugin-commonjs';\nimport { terser } from 'rollup-plugin-terser';\n\nexport default {\n  input: 'src\/main.js',           \/\/ Entry point\n  output: {\n    file: 'dist\/math-demo.min.js',   \/\/ Output file\n    format: 'iife',               \/\/ IIFE for browsers\n    name: 'MathDemoApp',          \/\/ Global variable name\n    plugins: &#91;terser()]           \/\/ Minify output\n  },\n  plugins: &#91;nodeResolve(), commonjs()]\n};<\/code><\/pre>\n\n\n\n<p>This tells Rollup:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Start from <strong>main.js<\/strong>, gather everything it imports, and create a single file at <strong>dist\/math-demo.min.js<\/strong>.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Run the build<\/h3>\n\n\n\n<p>Execute the following command in your terminal now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npx rollup -c<\/code><\/pre>\n\n\n\n<p>and you should see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dist\/\n  math-demo.min.js<\/code><\/pre>\n\n\n\n<p>This file should have the following code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>!function(){\"use strict\";console.log(\"2 + 3 =\",2+3)}();<\/code><\/pre>\n\n\n\n<p>What happened? Where are <code>add()<\/code> and <code>multiply()<\/code>?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Understanding What Happened<\/h3>\n\n\n\n<p>Rollup started at <code>main.js<\/code> and built a dependency graph.<br>It noticed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You imported only <code>add<\/code>.<\/li>\n\n\n\n<li>You never used <code>multiply<\/code>.<\/li>\n<\/ul>\n\n\n\n<p>So during bundling, Rollup did tree-shaking and removed <code>multiply()<\/code> completely and gave us this code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(function () {\n  'use strict';\n\n  \/\/ src\/math.js\n  function add(a, b) {\n    return a + b;\n  }\n\n  \/\/ src\/main.js\n  console.log('2 + 3 =', add(2, 3));\n\n})();<\/code><\/pre>\n\n\n\n<p>Now it was Terser&#8217;s turn to do its magic and it does the following:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Remove whitespace and comments.<\/li>\n\n\n\n<li>Rename variables (if safe).<\/li>\n\n\n\n<li><strong>Inline trivial functions<\/strong> (this is what you noticed).<\/li>\n\n\n\n<li>Remove redundant return paths or scopes.<\/li>\n<\/ol>\n\n\n\n<p>Since your <code>add()<\/code> was:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function add(a, b) { return a + b; }<\/code><\/pre>\n\n\n\n<p>and it was only used once, Terser said:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>\u201cNo point keeping this function. I\u2019ll just replace <code>add(2, 3)<\/code> with <code>2 + 3<\/code>.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p>The end result was this code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>!function(){\"use strict\";console.log(\"2 + 3 =\",2+3)}();<\/code><\/pre>\n\n\n\n<p>You could replace the original <code>output<\/code> value in <strong>rollup.config.js<\/strong> with this one to create three different production ready files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>output: &#91;\n    {\n      file: 'dist\/math-demo.esm.js',\n      format: 'esm',\n    },\n    {\n      file: 'dist\/math-demo.min.js',\n      format: 'iife',\n      name: 'MathApp',\n      plugins: &#91;terser()]\n    },\n    {\n      file: 'dist\/math-demo.js',\n      format: 'iife',\n      name: 'MathApp'\n    }\n  ],<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Final Thoughts<\/h2>\n\n\n\n<p>Bundling may look like magic at first. One moment you have a folder full of small files, and the next you\u2019ve got a single <code>bundle.js<\/code> ready to run anywhere. But as you\u2019ve seen, it\u2019s just smart, systematic work: Rollup follows every <code>import<\/code>, removes the extras, and builds one efficient file for your browser, Node, or any environment you choose.<\/p>\n\n\n\n<p>Rollup stands out because it does this job with minimal setup and maximum clarity. You don\u2019t need a monster config or a web of plugins to get started just <code>input<\/code>, <code>output<\/code>, <code>format<\/code>, and <code>plugins<\/code>. Whether you\u2019re creating a small utility library or learning how build tools actually work, Rollup gives you a front-row seat to how modern JavaScript comes together behind the scenes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Peek inside a modern JavaScript project and you will probably see a folder called dist with some massive files inside it with names like colorful.min.js, colorful.esm.js, colorful.umd.js etc. Each of them is meant for a specific target and contain the entire optimized code of your project. Where did these files come from? A bundler creates [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":10277,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[],"class_list":["post-10260","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev-notes"],"_links":{"self":[{"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/posts\/10260","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/comments?post=10260"}],"version-history":[{"count":8,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/posts\/10260\/revisions"}],"predecessor-version":[{"id":10276,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/posts\/10260\/revisions\/10276"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/media\/10277"}],"wp:attachment":[{"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/media?parent=10260"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/categories?post=10260"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hellonitish.com\/blog\/wp-json\/wp\/v2\/tags?post=10260"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}