0
# rollup-plugin-node-externals
1
2
A Rollup/Vite plugin that automatically declares NodeJS built-in modules as external, preventing bundlers from trying to include them in the output bundle. Also handles npm dependencies by automatically marking dependencies, peerDependencies, and optionalDependencies as external while allowing devDependencies to be bundled.
3
4
## Package Information
5
6
- **Package Name**: rollup-plugin-node-externals
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install --save-dev rollup-plugin-node-externals`
10
11
## Core Imports
12
13
```typescript
14
import nodeExternals from "rollup-plugin-node-externals";
15
```
16
17
Named export:
18
19
```typescript
20
import { nodeExternals } from "rollup-plugin-node-externals";
21
```
22
23
Type imports:
24
25
```typescript
26
import type { ExternalsOptions } from "rollup-plugin-node-externals";
27
```
28
29
## Basic Usage
30
31
```typescript
32
// rollup.config.js
33
import nodeExternals from "rollup-plugin-node-externals";
34
35
export default {
36
input: "src/index.js",
37
output: {
38
file: "dist/bundle.js",
39
format: "cjs"
40
},
41
plugins: [
42
nodeExternals() // Uses default settings
43
]
44
};
45
```
46
47
For Vite:
48
49
```typescript
50
// vite.config.js
51
import { defineConfig } from "vite";
52
import nodeExternals from "rollup-plugin-node-externals";
53
54
export default defineConfig({
55
plugins: [
56
nodeExternals()
57
]
58
});
59
```
60
61
## Architecture
62
63
The plugin operates during Rollup's module resolution phase:
64
65
- **Build-time scanning**: Recursively scans package.json files from current directory up to git root or workspace root
66
- **Dependency mapping**: Collects dependencies based on configuration options (deps, devDeps, peerDeps, optDeps)
67
- **Node.js built-in handling**: Automatically detects and manages Node.js built-in modules with configurable prefix handling
68
- **Resolution filtering**: Uses include/exclude patterns for fine-grained control over external declarations
69
70
## Capabilities
71
72
### Plugin Factory Function
73
74
Creates a Rollup/Vite plugin instance with the specified configuration options.
75
76
```typescript { .api }
77
/**
78
* A Rollup/Vite plugin that automatically declares NodeJS built-in modules,
79
* and optionally npm dependencies, as 'external'.
80
*/
81
function nodeExternals(options?: ExternalsOptions): Plugin;
82
83
interface ExternalsOptions {
84
/**
85
* Mark node built-in modules like `path`, `fs`... as external.
86
* Defaults to `true`.
87
*/
88
builtins?: boolean;
89
90
/**
91
* node: prefix handing for importing Node builtins:
92
* - `'add'` turns `'path'` to `'node:path'`
93
* - `'strip'` turns `'node:path'` to `'path'`
94
* - `'ignore'` leaves Node builtin names as-is
95
* Defaults to `add`.
96
*/
97
builtinsPrefix?: 'add' | 'strip' | 'ignore';
98
99
/**
100
* Path/to/your/package.json file (or array of paths).
101
* Defaults to all package.json files found in parent directories recursively.
102
* Won't go outside of a git repository.
103
*/
104
packagePath?: string | string[];
105
106
/**
107
* Mark dependencies as external.
108
* Defaults to `true`.
109
*/
110
deps?: boolean;
111
112
/**
113
* Mark devDependencies as external.
114
* Defaults to `false`.
115
*/
116
devDeps?: boolean;
117
118
/**
119
* Mark peerDependencies as external.
120
* Defaults to `true`.
121
*/
122
peerDeps?: boolean;
123
124
/**
125
* Mark optionalDependencies as external.
126
* Defaults to `true`.
127
*/
128
optDeps?: boolean;
129
130
/**
131
* Force include these deps in the list of externals, regardless of other settings.
132
* Defaults to `[]` (force include nothing).
133
*/
134
include?: MaybeArray<MaybeFalsy<string | RegExp>>;
135
136
/**
137
* Force exclude these deps from the list of externals, regardless of other settings.
138
* Defaults to `[]` (force exclude nothing).
139
*/
140
exclude?: MaybeArray<MaybeFalsy<string | RegExp>>;
141
}
142
```
143
144
**Configuration Examples:**
145
146
```typescript
147
// Include specific modules as external
148
nodeExternals({
149
deps: false, // Don't externalize dependencies
150
include: 'fsevents' // But force fsevents to be external
151
});
152
153
// Exclude specific modules from being external
154
nodeExternals({
155
deps: true, // Externalize dependencies
156
exclude: 'electron-reload' // But bundle electron-reload
157
});
158
159
// Complex filtering with regex
160
nodeExternals({
161
include: [/^lodash/, 'chalk'], // Externalize lodash/* and chalk
162
exclude: /test-/ // Bundle anything starting with 'test-'
163
});
164
165
// Custom package.json paths for monorepos
166
nodeExternals({
167
packagePath: [
168
'./package.json',
169
'./packages/core/package.json'
170
]
171
});
172
173
// Node.js built-in prefix handling
174
nodeExternals({
175
builtinsPrefix: 'strip' // 'node:path' becomes 'path'
176
});
177
```
178
179
### Built-in Node.js Modules Handling
180
181
The plugin automatically detects and manages Node.js built-in modules (like `fs`, `path`, `os`) with configurable prefix handling.
182
183
```typescript { .api }
184
/**
185
* Built-in module prefix handling options
186
*/
187
type BuiltinsPrefix = 'add' | 'strip' | 'ignore';
188
```
189
190
- **`'add'` (default)**: Ensures `node:` prefix is always present (`'path'` → `'node:path'`)
191
- **`'strip'`**: Removes `node:` prefix when possible (`'node:path'` → `'path'`)
192
- **`'ignore'`**: Leaves imports exactly as written in source code
193
194
### Dependency Management
195
196
The plugin scans package.json files to determine which modules should be treated as external based on dependency type configuration.
197
198
```typescript { .api }
199
/**
200
* Dependency type configuration options
201
*/
202
interface DependencyOptions {
203
deps?: boolean; // Runtime dependencies (default: true)
204
devDeps?: boolean; // Development dependencies (default: false)
205
peerDeps?: boolean; // Peer dependencies (default: true)
206
optDeps?: boolean; // Optional dependencies (default: true)
207
}
208
```
209
210
### Include/Exclude Filtering
211
212
Fine-grained control over which modules are treated as external using string or regex patterns.
213
214
```typescript { .api }
215
/**
216
* Module filtering configuration
217
*/
218
interface FilterOptions {
219
include?: MaybeArray<MaybeFalsy<string | RegExp>>;
220
exclude?: MaybeArray<MaybeFalsy<string | RegExp>>;
221
}
222
```
223
224
**Pattern Matching:**
225
- String patterns are converted to exact match regex
226
- Subpath imports are supported (e.g., `lodash` matches `lodash/map`)
227
- Falsy values in arrays are silently ignored for conditional logic
228
229
### Package Path Resolution
230
231
The plugin automatically discovers package.json files for dependency scanning, with support for monorepos and custom paths.
232
233
```typescript { .api }
234
/**
235
* Package path configuration for dependency scanning
236
*/
237
interface PackagePathOptions {
238
packagePath?: string | string[];
239
}
240
```
241
242
**Default behavior** (when `packagePath` is not specified):
243
1. Starts from current working directory
244
2. Scans upward through parent directories
245
3. Stops at git repository root or workspace root markers
246
4. Collects all package.json files found
247
248
**Workspace root detection** looks for:
249
- `pnpm-workspace.yaml` (pnpm)
250
- `lerna.json` (Lerna)
251
- `rush.json` (Rush)
252
253
## Types
254
255
```typescript { .api }
256
/**
257
* Utility type for nullable/falsy values
258
*/
259
type MaybeFalsy<T> = T | undefined | null | false;
260
261
/**
262
* Utility type for single value or array
263
*/
264
type MaybeArray<T> = T | T[];
265
266
/**
267
* Vite-compatible plugin interface extending Rollup's Plugin
268
*/
269
interface ViteCompatiblePlugin extends Plugin {
270
apply?: 'build' | 'serve';
271
enforce?: 'pre' | 'post';
272
}
273
274
/**
275
* Package.json structure used for dependency scanning
276
*/
277
interface PackageJson {
278
name: string;
279
version: string;
280
workspaces?: string[];
281
dependencies?: Record<string, string>;
282
devDependencies?: Record<string, string>;
283
peerDependencies?: Record<string, string>;
284
optionalDependencies?: Record<string, string>;
285
}
286
```
287
288
## Usage Notes
289
290
### Plugin Ordering
291
This plugin should be placed **first** in the plugins array to ensure proper module resolution:
292
293
```typescript
294
export default {
295
plugins: [
296
nodeExternals(), // First
297
nodeResolve(), // After
298
// other plugins...
299
]
300
};
301
```
302
303
### Monorepo Support
304
The plugin automatically handles monorepos by:
305
- Scanning multiple package.json files
306
- Detecting workspace configurations
307
- Breaking early when workspace root is found
308
309
### Vite Compatibility
310
The plugin includes Vite-specific properties:
311
- `apply: 'build'` - Only runs during build phase
312
- `enforce: 'pre'` - Runs early in the resolution process
313
314
### Error Handling
315
The plugin provides clear error messages for:
316
- Invalid package.json files
317
- Unreadable package paths
318
- Malformed configuration options