rollup / plugins

🍣 The one-stop shop for official Rollup plugins
MIT License
3.57k stars 568 forks source link

node-resolve: allow more granular config of preferBuiltins #1655

Open davidje13 opened 6 months ago

davidje13 commented 6 months ago

Feature Use Case

Some NodeJS builtins (e.g. punycode) are deprecated, and replacement packages with the same name exist in NPM. It is desirable to have preferBuiltins set to false for these specific cases, while keeping it true for all other builtins (e.g. string_decoder is also available as both a builtin and a package, but in this case the builtin is stable and should be preferred).

Feature Proposal

Allow preferBuiltins to accept a regex, array, or function, matching the behaviour of e.g. external. The relevant code is already considering these on an import-by-import basis, so it should be possible without any restructuring needed.

For example, the config for the punycode example above could be:

nodeResolve({
  preferBuiltins: (module) => module !== 'punycode',
})

(perhaps an even better API would be to reverse the config, preferring builtins by default and offering a preferModules config, since that would allow preferModules: ['punycode'], but that is not backwards-compatible, or at least introduces ambiguity if both options are used)

davidje13 commented 6 months ago

In cases where the deprecated module is the only one that exists as both a builtin and a module, it is currently possible to use preferBuiltins: false, but this also requires listing all standard builtins explicitly as external:

import { builtinModules } from 'module';

const modules = new Set(builtinModules);
modules.delete('punycode'); // we have to remove the entry that we WANT to be replaced

export default {
  plugins: [nodeResolve({ preferBuiltins: false })],
  external: [/^node:/, ...modules], // prevent warnings during build
};

This is not required when using preferBuiltins: true:

export default {
  plugins: [nodeResolve({ preferBuiltins: true })],
  external: [], // no need to explicitly list builtin modules
};

So even in this case, having finer control over preferBuiltins would be beneficial.