Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/node-resolve/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,13 @@ Specifies the properties to scan within a `package.json`, used to determine the

### `preferBuiltins`

Type: `Boolean`<br>
Type: `Boolean | 'prefer-protocol' | 'prefer-no-protocol'`<br>
Default: `true` (with warnings if a builtin module is used over a local version. Set to `true` to disable warning.)

If `true`, the plugin will prefer built-in modules (e.g. `fs`, `path`). If `false`, the plugin will look for locally installed modules of the same name.

When set to `true`, `prefer-protocol` and `prefer-no-protocol` can also be used to deduplicate, e.g. `fs` and `node:fs`, as the same module. The final import path would be `node:fs` for `prefer-protocol` or `fs` for `prefer-no-protocol`.

### `modulesOnly`

Type: `Boolean`<br>
Expand Down
16 changes: 14 additions & 2 deletions packages/node-resolve/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function nodeResolve(opts = {}) {
const idToPackageInfo = new Map();
const mainFields = getMainFields(options);
const useBrowserOverrides = mainFields.indexOf('browser') !== -1;
const isPreferBuiltinsSet = options.preferBuiltins === true || options.preferBuiltins === false;
const isPreferBuiltinsSet = options.preferBuiltins != null;
const preferBuiltins = isPreferBuiltinsSet ? options.preferBuiltins : true;
const rootDir = resolve(options.rootDir || process.cwd());
let { dedupe } = options;
Expand Down Expand Up @@ -214,7 +214,19 @@ export function nodeResolve(opts = {}) {
`preferring built-in module '${importee}' over local alternative at '${resolvedWithoutBuiltins.location}', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning`
);
}
return false;
if (preferBuiltins === true) {
return false;
} else if (preferBuiltins === 'prefer-protocol') {
if (!importee.startsWith('node:')) {
importee = `node:${importee}`;
}
return { id: importee, external: true };
} else if (preferBuiltins === 'prefer-no-protocol') {
if (importee.startsWith('node:')) {
importee = importee.slice(5);
}
return { id: importee, external: true };
}
} else if (jail && location.indexOf(normalize(jail.trim(sep))) !== 0) {
return null;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/node-resolve/test/fixtures/node-dedupe-protocol.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'fs';
import 'node:fs';
36 changes: 36 additions & 0 deletions packages/node-resolve/test/prefer-builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,39 @@ test('detects builtins imported with node: protocol', async (t) => {

t.is(warnings.length, 0);
});

test('dedupe builtins for prefer-protocol', async (t) => {
const warnings = [];
const bundle = await rollup({
input: 'node-dedupe-protocol.js',
onwarn: (warning) => warnings.push(warning),
plugins: [
nodeResolve({
preferBuiltins: 'prefer-protocol'
})
]
});

const imports = await getImports(bundle);

t.is(warnings.length, 0);
t.deepEqual(imports, ['node:fs']);
});

test('dedupe builtins for prefer-no-protocol', async (t) => {
const warnings = [];
const bundle = await rollup({
input: 'node-dedupe-protocol.js',
onwarn: (warning) => warnings.push(warning),
plugins: [
nodeResolve({
preferBuiltins: 'prefer-no-protocol'
})
]
});

const imports = await getImports(bundle);

t.is(warnings.length, 0);
t.deepEqual(imports, ['fs']);
});
6 changes: 5 additions & 1 deletion packages/node-resolve/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,13 @@ export interface RollupNodeResolveOptions {
/**
* If `true`, the plugin will prefer built-in modules (e.g. `fs`, `path`). If `false`,
* the plugin will look for locally installed modules of the same name.
*
* When set to `true`, `prefer-protocol` and `prefer-no-protocol` can also be used to
* deduplicate, e.g. `fs` and `node:fs`, as the same module. The final import path would
* be `node:fs` for `prefer-protocol` or `fs` for `prefer-no-protocol`.
* @default true
*/
preferBuiltins?: boolean;
preferBuiltins?: boolean | 'prefer-protocol' | 'prefer-no-protocol';

/**
* An `Array` which instructs the plugin to limit module resolution to those whose
Expand Down