Skip to content

[Feature Request]: Make require('external') runnable in any execution context if possible #2685

Description

@sapphi-red

What problem does this feature solve?

When a CJS file requires an external module commonly builtin modules like node:path, Error: Dynamic require of "*" is not supported is thrown for the output bundle.

Reproduction steps

  1. Open https://stackblitz.com/edit/github-xv4yss-2sb9fe?file=rolldown.config.mjs,src%2Fentry.js,src%2Fa.cjs
  2. npm i runs automatically
  3. npm run build runs automatically
  4. run node dist/entry.js. It errors with Error: Dynamic require of "node:path" is not supported.
  5. run npm run build:up to use rollup
  6. run node dist/entry.js. It runs successfully.

Workarounds

I'm setting

banner: "import { createRequire as ___createRequire } from 'module'; const require = ___createRequire(import.meta.url);",

like when I encounter evanw/esbuild#1921.

What does the proposed API look like?

For platform: 'node', it should be safe to use import module from 'node:module'; const require = module.createRequire(import.meta.url) for it.
For other platforms, I guess converting require into import is what users want in most cases. This may lead to crash in some cases due to incompatibility of module.exports / export *, so probably we need an option to control the interop code like requireReturnsDefault option in @rollup/plugin-commonjs.

For any platforms, I guess the node builtins can be treated as it's safe to convert require into import even if it's externalized. probably this isn't safe due to hoisting?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions