https://github.com/hyrious/esbuild-plugin-commonjs
An esbuild plugin to help you bundle commonjs external modules.
https://github.com/hyrious/esbuild-plugin-commonjs
Last synced: about 1 year ago
JSON representation
An esbuild plugin to help you bundle commonjs external modules.
- Host: GitHub
- URL: https://github.com/hyrious/esbuild-plugin-commonjs
- Owner: hyrious
- License: mit
- Created: 2022-01-06T10:58:52.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2025-02-18T05:53:19.000Z (about 1 year ago)
- Last Synced: 2025-04-03T03:09:14.850Z (about 1 year ago)
- Language: TypeScript
- Homepage:
- Size: 92.8 KB
- Stars: 30
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# @hyrious/esbuild-plugin-commonjs
An esbuild plugin to help you bundle commonjs external modules.
This plugin is used to address [evanw/esbuild#1467][1], 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:
```js
// some commonjs library, like react-dom
var React = require('react')
// your esm code
export { render } from 'react-dom'
// after esbuild --bundle
var React = __require('react') // <- you dislike this
// ...
export { render }
// with this plugin
import __import_react from 'react' // <- you want this
var React = __import_react
// ...
export { render }
```
This plugin was inspired by [a comment under esbuild#1921][4]
and the [prototype][5] was done after a day.
## Install
```bash
npm add -D @hyrious/esbuild-plugin-commonjs
```
## Usage
```js
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
```js
commonjs({ filter: /\.c?js$/, transform: false })
```
**filter** (default: `/\.c?js$/`)
A RegExp passed to [`onLoad()`](https://esbuild.github.io/plugins/#on-load) to
match commonjs modules, it is recommended to set a custom filter to skip files
for better performance.
**requireReturnsDefault** (default: `true`)
```ts
requireReturnsDefault: boolean | ((path: string) => boolean)
```
Controls which style of import statement to use replacing require calls in commonjs modules.
```js
// input
const foo = require('foo')
// output if requireReturnsDefault is true (default behavior)
import foo from 'foo'
// output if requireReturnsDefault is false
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.
```ts
ignore: string[] | ((path: string) => boolean)
```
**transform** (default: `false`)
Try to transform commonjs to es modules. This trick is done with [`cjs-module-lexer`](https://github.com/nodejs/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.
```ts
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:
```js
exports.__esModule = true
exports.default = {}
exports.foo = 42
```
To this:
```js
var exports = {}, module = { exports };
{
exports.__esModule = true;
exports.default = {};
exports.foo = 42;
}
export default exports;
var { foo } = exports;
export { foo };
```
## This is not equal to [@rollup/plugin-commonjs][2].
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][3] 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.5
Fix: skip shebangs when injecting import statements. ([#6](https://github.com/hyrious/esbuild-plugin-commonjs/issues/6))
### 0.2.4
Add options `requireReturnsDefault` and `ignore`.
### 0.2.0
Add experimental option `transform` and `transformConfig`.
## License
MIT @ [hyrious](https://github.com/hyrious)
[1]: https://github.com/evanw/esbuild/issues/1467
[2]: https://github.com/rollup/plugins/blob/master/packages/commonjs
[3]: https://github.com/evanw/esbuild/issues/1919
[4]: https://github.com/evanw/esbuild/issues/1921#issuecomment-1010490128
[5]: https://gist.github.com/hyrious/7120a56c593937457c0811443563e017