@hyrious/esbuild-plugin-commonjs
An esbuild plugin to help you bundle commonjs external modules.
This plugin is used to address evanw/esbuild#1467, where you want to
bundle some commonjs external modules in es modules context. But accidentally
you see a __require
in your code prints error at runtime and forbids
other bundlers from analyzing the dependencies. For example:
var React = require('react')
export { render } from 'react-dom'
var React = __require('react')
export { render }
import __import_react from 'react'
var React = __import_react
export { render }
This plugin was inspired by a comment under esbuild#1921
and the prototype was done after a day.
Install
npm add -D @hyrious/esbuild-plugin-commonjs
Usage
const { commonjs } = require("@hyrious/esbuild-plugin-commonjs");
require("esbuild").build({
entryPoints: ["lib.js"],
bundle: true,
format: "esm",
external: ["react"],
outfile: "out.js",
plugins: [commonjs()],
}).catch(() => process.exit(1));
Options
commonjs({ filter: /\.c?js$/, transform: false })
filter (default: /\.c?js$/
)
A RegExp passed to onLoad()
to
match commonjs modules, it is recommended to set a custom filter to skip files
for better performance.
requireReturnsDefault (default: true
)
requireReturnsDefault: boolean | ((path: string) => boolean)
Controls which style of import statement to use replacing require calls in commonjs modules.
const foo = require('foo')
import foo from 'foo'
import * as foo from 'foo'
ignore
Do not convert require calls to these modules. Note that this will cause esbuild
to generate __require()
wrappers and throw errors at runtime.
ignore: string[] | ((path: string) => boolean)
transform (default: false
)
Try to transform commonjs to es modules. This trick is done with cjs-module-lexer
to match the native (node) behavior as much as possible. Because this
transformation may cause many bugs around the interop between cjs and esm,
it can also accept a function to filter in the "safe to convert" modules by yourself.
transform: boolean | ((path: string) => {
behavior?: "node" | "babel", exports?: string[], sideEffects?: boolean
} | null | void)
By default, if you toggle transform
to true
, it will convert this code:
exports.__esModule = true
exports.default = {}
exports.foo = 42
To this:
var exports = {}, module = { exports };
{
exports.__esModule = true;
exports.default = {};
exports.foo = 42;
}
export default exports;
var { foo } = exports;
export { foo };
This plugin does not convert your commonjs file into es modules, it just
replace those require("x")
expressions with import statements. It turns out
that esbuild can handle this kind of mixed module (having import statement and
module.exports
at the same time) correctly.
The one acting the same exists in the branch rollup
, but is not a good
solution. It depends on a feature syntheticNamedExports
and evanw
(the author of esbuild) doesn't want to implement something out of spec.
Without which you have to tell the plugin every single commonjs file's named
exports, which sucks obviously.
Changelog
0.2.0
Add experimental option transform
and transformConfig
.
0.2.3
Add options requireReturnsDefault
and ignore
.
License
MIT @ hyrious