Security News
vlt Debuts New JavaScript Package Manager and Serverless Registry at NodeConf EU
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
rollup-plugin-node-externals
Advanced tools
Automatically declare NodeJS built-in modules and npm dependencies as 'external' in Rollup config
A Rollup plugin that automatically declares NodeJS built-in modules as external
. Also handles npm dependencies, devDependencies, peerDependencies and optionalDependencies.
Works in npm/yarn/pnpm/lerna monorepos too!
By default, Rollup doesn't know a thing about NodeJS, so trying to bundle simple things like import path from 'node:path'
in your code generates an Unresolved dependencies
warning.
The solution here is quite simple: you must tell Rollup that the node:path
module is in fact external. This way, Rollup won't try to bundle it in and rather leave the import
statement as is (or translate it to a require()
call if bundling for CommonJS).
However, this must be done for each and every NodeJS built-in you happen to use in your program: node:path
, node:os
, node:fs
, node:url
, etc., which can quickly become cumbersome when done manually.
So the primary goal of this plugin is simply to automatically declare all NodeJS built-in modules as external.
As an added bonus, this plugin will also allow you to declare your dependencies (as per your local or monorepo package.json
file(s)) as external.
Use your favorite package manager. Mine is npm.
npm install --save-dev rollup-plugin-node-externals
The plugin is available both as the default export and as a named export:
import nodeExternals from 'rollup-plugin-node-externals'
and
import { nodeExternals } from 'rollup-plugin-node-externals'
will both work.
Note: an undocumented named export
externals
also exists that is kept in v6.1 for backwards compatibility only and will be removed in the next major version.
You generally want to have your runtime dependencies (those that will be imported/required at runtime) listed under dependencies
in package.json
, and your development dependencies (those that should be bundled in by Rollup) listed under devDependencies
.
If you follow this simple rule, then the default settings are just what you need:
// rollup.config.js
export default {
...
plugins: [
nodeExternals(),
]
}
This will bundle your devDependencies
in while leaving your dependencies
, peerDependencies
and optionalDependencies
external.
Should the defaults not suit your case, here is the full list of options.
import nodeExternals from 'rollup-plugin-node-externals'
export default {
...
plugins: [
nodeExternals({
// Make node builtins external. Default: true.
builtins?: boolean
// node: prefix handing for importing Node builtins. Default: 'add'.
builtinsPrefix?: 'add' | 'strip' | 'ignore'
// The path(s) to your package.json. See below for default.
packagePath?: string | string[]
// Make pkg.dependencies external. Default: true.
deps?: boolean
// Make pkg.devDependencies external. Default: false.
devDeps?: boolean
// Make pkg.peerDependencies external. Default: true.
peerDeps?: boolean
// Make pkg.optionalDependencies external. Default: true.
optDeps?: boolean
// Modules to force include in externals. Default: [].
include?: string | RegExp | (string | RegExp)[]
// Modules to force exclude from externals. Default: [].
exclude?: string | RegExp | (string | RegExp)[]
})
]
}
Set the builtins
option to false
if you'd like to use some shims/polyfills for those. You'll most certainly need an other plugin as well.
How to handle the node:
scheme used in recent versions of Node (i.e., import path from 'node:path'
).
add
(the default, recommended), the node:
prefix is always added. In effect, this homogenizes all your imports of Node builtins to their prefixed version.strip
, the prefix is always removed. In effect, this homogenizes all your imports of Node builtins to their unprefixed version.ignore
will simply leave all builtins imports as written in your code.Note that prefix handling is always applied, regardless of the
builtins
options being enabled or not.
If you're working with monorepos, the packagePath
option is made for you. It can take a path, or an array of paths, to your package.json file(s). If not specified, the default is to start with the current directory's package.json then go up scan for all package.json
files in parent directories recursively until either the root git directory is reached or until no other package.json
can be found.
Set the deps
, devDeps
, peerDeps
and optDeps
options to false
to prevent the corresponding dependencies from being externalized, therefore letting Rollup bundle them with your code.
Use the include
option to force certain dependencies into the list of externals, regardless of other settings:
nodeExternals({
deps: false, // Deps will be bundled in
include: 'fsevents' // Except for fsevents
})
Conversely, use the exclude
option to remove certain dependencies from the list of externals, regardless of other settings:
nodeExternals({
deps: true, // Keep deps external
exclude: 'electron-reload' // Yet we want `electron-reload` bundled in
})
include
and exclude
are silently ignored. This allows for conditional constructs like exclude: process.env.NODE_ENV === 'production' && 'my-prod-only-dep'
.include: /^lodash/
will externalize lodash
and also lodash/map
, lodash/merge
, etc.It uses an exact match against your imports as written in your code, so if your are using some kind of path substitution, eg.:
// In your code, say '@/' is mapped to some directory:
import something from '@/mylib'
and you don't want mylib
bundled in, then write:
// In rollup.config.js:
nodeExternals({
include: '@/mylib'
})
If you're also using @rollup/plugin-node-resolve
, make sure this plugin comes before it in the plugins
array:
import nodeExternals from 'rollup-plugin-node-externals'
import nodeResolve from '@rollup/plugin-node-resolve'
export default {
...
plugins: [
nodeExternals(),
nodeResolve(),
]
}
As a general rule of thumb, you might want to always make this plugin the first one in the plugins
array.
Rollup's own external
configuration option always takes precedence over this plugin. This is intentional.
^3.0.0 || ^4.0.0
.devDeps
option defaulted to true
.devDeps
option now defaults to false
, meaning Rollup will include them in your bundle.builtinsPrefix
option now defaults to 'add'
.prefixedBuiltins
option has been removed. Use builtinsPrefix
instead.rollup-plugin-node-externals
no longer depends on the Find-Up package (while this is not a breaking change per se, it can be in some edge situations).rollup ^2.60.0 || ^3.0.0
.deps
option defaulted to false
.deps
option now defaults to true
.rollup ^2.60.0
.MIT
FAQs
Automatically declare NodeJS built-in modules and npm dependencies as 'external' in Rollup config
The npm package rollup-plugin-node-externals receives a total of 84,183 weekly downloads. As such, rollup-plugin-node-externals popularity was classified as popular.
We found that rollup-plugin-node-externals demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt introduced its new package manager and a serverless registry this week, innovating in a space where npm has stagnated.
Security News
Research
The Socket Research Team uncovered a malicious Python package typosquatting the popular 'fabric' SSH library, silently exfiltrating AWS credentials from unsuspecting developers.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.