DEV Community

BHARGAB KALITA
BHARGAB KALITA

Posted on

Rollup.js Made Easy: A Step-by-Step Guide to Building and Publishing NPM Packages

Rollup.js is a fantastic tool for bundling JavaScript and TypeScript libraries, especially when you’re aiming for top-notch performance and smooth integration. Unlike other bundlers, Rollup focuses on creating smaller, optimized code by utilizing ES modules. If you’re looking to build efficient packages, Rollup is your go-to choice.

In this post, we’ll explore Rollup’s key features, guide you through setting it up for package building, show you how to test your package locally, then publishing it to NPM. We’ll also highlight some essential plugins to enhance your build process, handle CSS files and images, and configure TypeScript for your project.


What is Rollup.js?

Rollup.js is a module bundler for JavaScript and TypeScript that compiles small pieces of code into something larger, like a library or application. It takes advantage of ES modules to streamline your code, removing unused elements and resulting in bundles that are smaller and faster.

Key Features of Rollup.js

  1. Tree-Shaking: Automatically removes unused code, slimming down the final bundle and boosting efficiency.
  2. ES Module Support: Rollup uses ES module syntax (import and export), which is ideal for modern JavaScript development.
  3. Plugins: Easily extensible with plugins that add functionality, such as handling non-JS files or minifying output.
  4. Code Splitting: Allows splitting of bundles, which is particularly useful for larger applications or libraries.
  5. Output Formats: Supports a variety of output formats like CommonJS, ES Modules, UMD, and IIFE, making it versatile for different project needs.
  6. Performance Optimizations: Rollup produces highly optimized code with smaller bundle sizes, making it perfect for performance-critical applications.

Setting Up Rollup.js for Building Packages

Let’s dive into setting up Rollup.js to build a package with React.js and TypeScript.

1. Install Rollup and Basic Dependencies

First, let’s get Rollup and some essential plugins installed:

npm install -D rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript rollup-plugin-peer-deps-external rollup-plugin-postcss tslib @rollup/plugin-image rollup-plugin-terser
Enter fullscreen mode Exit fullscreen mode

Here’s what each plugin does:

  • @rollup/plugin-node-resolve: Helps Rollup find third-party modules in node_modules.
  • @rollup/plugin-commonjs: Converts CommonJS modules to ES modules so Rollup can handle them.
  • @rollup/plugin-typescript: Compiles TypeScript files seamlessly.
  • rollup-plugin-peer-deps-external: Automatically marks peer dependencies as external, keeping your bundle light.
  • rollup-plugin-postcss: Processes and bundles CSS, which is crucial for handling styles in React components.
  • @rollup/plugin-image: Allows images to be imported directly into your components.
  • rollup-plugin-terser: Minifies the output, reducing file size and improving load times.
  • tslib: This is a runtime library for TypeScript that contains all of the TypeScript helper functions.

2. Setting Up TypeScript Configuration

Create a tsconfig.json in your project root to configure TypeScript:

{
    "compilerOptions": {
      "target": "ES6",
      "module": "ESNext",
      "jsx": "react",
      "declaration": true,
      "declarationDir": "./",
      "rootDir": "./src",
      "outDir": "./dist",
      "strict": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "sourceMap": true,
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules", "dist"]
}
Enter fullscreen mode Exit fullscreen mode

This configuration ensures your TypeScript code is compiled correctly and efficiently.

3. Create a Basic Rollup Configuration

Next, create a rollup.config.js file in your project root:

import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import postcss from 'rollup-plugin-postcss';
import image from '@rollup/plugin-image';
import { terser } from 'rollup-plugin-terser';

export default {
  input: 'src/index.ts',
  output: [
    {
      file: 'dist/index.cjs.js',
      format: 'cjs',
      sourcemap: true,
    },
    {
      file: 'dist/index.esm.js',
      format: 'esm',
      sourcemap: true,
    },
  ],
  plugins: [
    peerDepsExternal(),
    resolve(),
    commonjs(),
    typescript({
      tsconfig: './tsconfig.json',
      declaration: true,
      declarationDir: './',
      rootDir: './src',
    }),
    postcss(),
    image(),
    terser(),
  ],
  external: ['react', 'react-dom'],
};
Enter fullscreen mode Exit fullscreen mode

Building and Watching with Rollup

To make your development process smoother, add these scripts to your package.json:

"scripts": {
  "build": "rollup -c",
  "watch": "rollup -c --watch"
}
Enter fullscreen mode Exit fullscreen mode

Now, you can build your package or watch for changes and rebuild automatically during development.

Testing Your Rollup Package Locally

Before publishing, it’s essential to test your package locally. Two effective ways are npm pack and npm link.

1. Testing with npm pack

npm pack simulates the npm install process, letting you test how your package would behave once published.

  1. Run:
   npm pack
Enter fullscreen mode Exit fullscreen mode
  1. This creates a .tgz file in your project directory.

  2. To test, install it in another project:

   npm install ../path-to-your-package/your-package-name-version.tgz
Enter fullscreen mode Exit fullscreen mode

2. Testing with npm link

npm link lets you link your package globally and use it across projects without publishing.

  1. Inside your package project, run:
   npm link
Enter fullscreen mode Exit fullscreen mode
  1. Then, in the project where you want to use the package, run:
   npm link your-package-name
Enter fullscreen mode Exit fullscreen mode

Handling CSS Files and Images in Rollup

Here’s how to handle CSS and images in your Rollup setup:

1. Handling CSS

Using rollup-plugin-postcss, you can process and bundle CSS files, even extracting them into separate files.

import postcss from 'rollup-plugin-postcss';

export default {
  plugins: [
    postcss({
      extract: true,
      minimize: true,
      modules: true,
    }),
  ],
};
Enter fullscreen mode Exit fullscreen mode

2. Handling Images

@rollup/plugin-image makes it easy to import images directly, and you can optimize them with additional plugins like imagemin.

import image from '@rollup/plugin-image';

export default {
  plugins: [
    image(),
    // Add further image optimization here if needed
  ],
};
Enter fullscreen mode Exit fullscreen mode

Publishing Your Package to npm

With Rollup set up, the final step is to publish your package on npm:

1. Prepare Your package.json

Ensure that your package.json includes essential details such as name, version, main, and files. Additionally, always use semantic versioning for versioning.

{
  "name": "my-awesome-package", // The name of your package
  "version": "1.0.0",           // Version number
  "description": "A description of what your package does.",
  "main": "dist/index.cjs.js",  // Entry point for CommonJS
  "module": "dist/index.esm.js", // Entry point for ES Modules
  "types": "dist/types/index.d.ts", // Entry point for TypeScript declarations
  "scripts": {
    "build": "rollup -c",
    "watch": "rollup -c --watch",
  },
  "files": [                    // Specify which files to include in the npm package
    "dist"
  ],
  "repository": {
    "type": "git",
    "url": "git+https://github.com/your-username/your-repo.git"
  },
  "keywords": ["microfrontend", "rollup", "typescript", "react"],
  "author": "Your Name",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/your-username/your-repo/issues"
  },
  "homepage": "https://github.com/your-username/your-repo#readme",
  "dependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "@rollup/plugin-commonjs": "^26.0.1",
    "@rollup/plugin-image": "^3.0.3",
    "@rollup/plugin-node-resolve": "^15.2.3",
    "@rollup/plugin-typescript": "^11.1.6",
    "rollup": "^2.79.1",
    "rollup-plugin-peer-deps-external": "^2.2.4",
    "rollup-plugin-postcss": "^4.0.2",
    "rollup-plugin-terser": "^7.0.2",
    "tslib": "^2.7.0",
    "typescript": "^5.5.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

2. Log In and Publish to npm

If you’re not logged in, use:

npm login
Enter fullscreen mode Exit fullscreen mode

Then, build your package:

npm run build
Enter fullscreen mode Exit fullscreen mode

And publish it:

npm publish --access public
Enter fullscreen mode Exit fullscreen mode

Now, your package is live on npm, ready for anyone to install with:

npm install my-awesome-package
Enter fullscreen mode Exit fullscreen mode

GitHub Repository:

To access the codebase, please visit the dedicated GitHub repository:

GitHub Repository: create-your-own-package

Feel free to clone the repository, explore the code, and use it as a reference for your own projects. If you encounter any issues or have questions, don't hesitate to open an issue on the repository. Your feedback and contributions are highly appreciated.


Conclusion

Rollup.js is a powerhouse for building efficient and optimized packages. Its modularity, plugin support, and ES module compatibility make it invaluable for developers. Whether you're crafting a simple package or tackling complex micro-frontends, Rollup.js provides the tools you need for streamlined, high-quality builds.

You can apply the same configuration approach to build a micro-frontend, leveraging Rollup's flexibility to create modular and reusable components. Just be sure to research the plugins you include to avoid unnecessary dependencies and keep your build process lean and efficient.

And there you have it! With Rollup.js in your toolkit, you’re all set to bundle your projects like a pro. As you navigate the sea of code, remember to enjoy the journey—after all, it's not just about the destination, but how you bundle along the way! 🚀

Happy bundling, and may your code be ever concise and your builds ever smooth! 😁

Top comments (0)