Skip to content

[Feature Request]: Support transforming CJS require calls into ESM imports #2041

@AdrianGonz97

Description

@AdrianGonz97

What problem does this feature solve?

Rolldown's current internal implementation of @rollup/plugin-commonjs is seemingly missing the feature of transforming CJS require calls into ESM imports when outputting to an esm format.

At the moment, the require calls remain in place, making it impossible to run the outputted code in node when the package.json type is set to type: "module":

➜  node dist-rolldown                            
file:///home/koala/Reproductions/rolldown-missing-transformation/dist-rolldown/index.js:28
        const path = require("node:path");
                     ^

ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and '/home/koala/Reproductions/rolldown-missing-transformation/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///home/koala/Reproductions/rolldown-missing-transformation/dist-rolldown/index.js:28:15
    at file:///home/koala/Reproductions/rolldown-missing-transformation/dist-rolldown/index.js:9:48
    at file:///home/koala/Reproductions/rolldown-missing-transformation/dist-rolldown/index.js:35:31
    at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)

Node.js v20.17.0

What does the proposed API look like?

Reproduction: https://github.com/AdrianGonz97/rolldown-missing-cjs-transformation.git

Input:

// entry.ts
import { foo } from "./commonjs.cjs";

console.log(foo);
// commonjs.cjs
const path = require("path");

const foo = path.resolve(".");

module.exports = { foo };

Output:

Rolldown (fails to execute in type: "module" mode):

//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports);
var __copyProps = (to, from, except, desc) => {
	if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
		key = keys[i];
		if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
			get: ((k) => from[k]).bind(null, key),
			enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
		});
	}
	return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
	value: mod,
	enumerable: true
}) : target, mod));

//#endregion
//#region commonjs.cjs
var require_commonjs = __commonJSMin((exports, module) => {
	const path = require("node:path");
	const foo$1 = path.resolve(".");
	module.exports = {foo: foo$1};
});

//#endregion
//#region entry.js
var import_commonjs = __toESM(require_commonjs());
console.log(import_commonjs.foo);

//#endregion

Rollup's @rollup/plugin-commonjs plugin (works as expected):

import require$$0 from 'path';

const path = require$$0;

const foo = path.resolve(".");

var commonjs = { foo };

console.log(commonjs.foo);

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions