Rollup Plugin for Node.js Polyfills
The `rollup-plugin-polyfill-node` package, currently at version `0.13.0`, provides a comprehensive solution for bundling applications that rely on Node.js built-in modules with Rollup. It acts as a modern, actively maintained fork of `rollup-plugin-node-polyfills`, offering improved and more complete polyfills. The package distinguishes itself by offering ES6-specific polyfills for many modules (like `process`, `events`, `util`), enabling named imports for better tree-shaking where applicable. Its development follows a community-driven release cadence, meaning updates are dependent on contributor engagement rather than a fixed schedule. It meticulously details the level of support for each Node.js builtin, from fully shimmed modules to partial implementations and empty mocks, crucial for developers migrating Node.js codebases to browser-compatible bundles via Rollup.
Common errors
-
Module not found: Can't resolve 'fs' in '...'
cause A Node.js builtin module is being imported or used in a Rollup bundle without the `rollup-plugin-polyfill-node` plugin correctly configured or present.fixEnsure `rollup-plugin-polyfill-node` is installed and added to your Rollup configuration's `plugins` array. Verify that the plugin's `include`/`exclude` options are not preventing the polyfill from applying to the relevant files. Often, `@rollup/plugin-node-resolve` should also be used with `preferBuiltins: false`. -
TypeError: (0 , vm.runInContext) is not a function
cause The `vm` module polyfill has limited support for all Node.js `vm` functionality, especially complex methods or specific corner cases, particularly in web worker environments.fixReview your usage of the `vm` module. If possible, refactor your code to avoid highly complex or specific `vm` features that may not be fully polyfilled. If `vm` is critical, consider a custom shim or re-evaluating the architectural need for `vm` in a bundled browser environment. -
Observed large bundle size despite tree-shaking efforts, particularly for modules related to Node.js streams or HTTP.
cause Complex polyfills like `stream` (and modules that depend on it, such as `http` and `https`) contain circular references that inherently limit Rollup's tree-shaking effectiveness, leading to larger bundle sizes than expected.fixFor critical bundle size concerns, evaluate if the specific Node.js modules are truly necessary in the bundled environment. If possible, refactor code to avoid heavy reliance on `stream`, `http`, or `https` polyfills, or consider using alternative, lighter-weight solutions or custom shims for minimal required functionality.
Warnings
- gotcha The `rollup-plugin-polyfill-node` package is entirely community-maintained. This implies that updates, bug fixes, and feature additions are reliant on community contributions, which may result in an irregular release schedule and potentially slower resolution of issues.
- gotcha Several complex Node.js built-in modules, including `http`, `https`, `stream`, `fs`, `crypto`, `vm`, and `perf_hooks`, offer only partial support or are known to have limitations. For example, `perf_hooks` is an empty shim, and `vm` has limited corner case support, especially in web worker environments.
- gotcha A significant number of Node.js builtins, such as `dns`, `dgram`, `child_process`, `cluster`, `module`, `net`, `readline`, `repl`, and `tls`, are not fully polyfilled but instead return empty mocks. This means any code attempting to use these modules will either receive null/empty objects or throw errors at runtime.
- gotcha Modules like `stream` (and anything that implicitly or explicitly relies on it, such as `http` and `https`) are known to involve complex circular references. This inherent complexity can significantly hinder Rollup's tree-shaking capabilities, leading to larger-than-expected bundle sizes.
- gotcha The `console` polyfill only provides a default export. The documentation explicitly advises users to utilize the global `console` object directly rather than attempting to import it from the polyfill.
Install
-
npm install rollup-plugin-polyfill-node -
yarn add rollup-plugin-polyfill-node -
pnpm add rollup-plugin-polyfill-node
Imports
- nodePolyfills
const nodePolyfills = require('rollup-plugin-polyfill-node');import nodePolyfills from 'rollup-plugin-polyfill-node';
- Node.js Builtin Modules
import EventEmitter from 'events';
import { EventEmitter } from 'events'; - Type imports
import type { RollupNodePolyfillOptions } from 'rollup-plugin-polyfill-node';
Quickstart
import nodePolyfills from 'rollup-plugin-polyfill-node';
import commonjs from '@rollup/plugin-commonjs';
import resolve from '@rollup/plugin-node-resolve';
// Basic Rollup configuration demonstrating node polyfills
export default {
input: 'src/main.js', // Your main application entry point
output: {
file: 'dist/bundle.js',
format: 'esm', // Output as ES module
},
plugins: [
// Resolve node modules, important for finding polyfills
resolve({
preferBuiltins: false, // Ensure polyfills are used instead of assuming native Node.js builtins
browser: true, // Hint to use browser-compatible versions where available
}),
// CommonJS plugin to convert CommonJS modules to ES modules
// This is often needed for node_modules that are not pure ESM
commonjs(),
// Apply the node polyfills
nodePolyfills({
// Optional: include or exclude specific files. By default, it processes node_modules/**/*.js
// include: [/node_modules/], // Example: explicitly include node_modules
// sourceMap: true, // Enable source maps for debugging
})
]
};