https://github.com/endel/esm-browser-node
Are frontend build tools compatible with Node.js/Browser targets?
https://github.com/endel/esm-browser-node
Last synced: 11 months ago
JSON representation
Are frontend build tools compatible with Node.js/Browser targets?
- Host: GitHub
- URL: https://github.com/endel/esm-browser-node
- Owner: endel
- Created: 2020-11-26T19:15:02.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-11-27T03:02:30.000Z (over 5 years ago)
- Last Synced: 2025-06-13T10:09:37.241Z (12 months ago)
- Language: JavaScript
- Homepage:
- Size: 217 KB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Broken ESM modules?
> Is it possible to have an ESM module that works both on Node.js and in the browser??
EXAMPLE: The `httpie` package specifies "browser" paths on its `package.json` multiple times, but frontend build tools don't seem to pick up the correct file - always selecting `node/index.mjs` (and failing because it has a built-in node dependency).

**Expectation:** When bundling a dependency that has both `"module"` and `"browser"` field, it is expected that the build-tool is going to use the **`"browser"`** version of it, since the **`"module"`** version is potentially targetted for Node.js (thus having a Node.js dependency inside)
**Reality:** Most build tools are trying to get the `"module"` version, and fail because the `"module"` version was made for Node.js and not browsers.
# Build tool
- [vite](#using-vite) ❌
- [snowpack](#using-snowpack) ❌
- [webpack](#using-webpack) ❌
- [esbuild](#using-esbuild) ✅
- [rollup](#using-rollup) ❌
## How to reproduce
## Using `vite`
```
cd vite
npm install
npm run dev
```
**file included:** `node/index.mjs` ❌
```
[vite] Dep optimization failed with error:
Could not load http (imported by node_modules/httpie/node/index.mjs): ENOENT: no such file or directory, open 'http'
[Error: Could not load http (imported by node_modules/httpie/node/index.mjs): ENOENT: no such file or directory, open 'http'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: 'http',
watchFiles: [
'/Users/endel/projects/vite-esm-browser-node/node_modules/httpie/node/index.mjs',
'/Users/endel/projects/vite-esm-browser-node/node_modules/vue/dist/vue.runtime.esm-bundler.js',
'/Users/endel/projects/vite-esm-browser-node/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js',
'/Users/endel/projects/vite-esm-browser-node/node_modules/@vue/shared/dist/shared.esm-bundler.js',
'/Users/endel/projects/vite-esm-browser-node/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js',
'/Users/endel/projects/vite-esm-browser-node/node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js',
'http',
'https',
'url'
]
}
```
## Using `snowpack`
```
cd snowpack
npm install
npm start
```
**file included:** `node/index.mjs` ❌
```
[snowpack] node_modules/httpie/node/index.mjs
Module "https" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
```
## Using `webpack`
```
cd webpack
npm install
npm start
```
**file included:** `node/index.mjs` ❌
```
ERROR in ./node_modules/httpie/node/index.mjs 1:0-32
Module not found: Error: Can't resolve 'https' in '/Users/endel/projects/esm-browser-node/webpack/node_modules/httpie/node'
```
## Using `esbuild`
```
cd esbuild
npm install
npm start
```
`esbuild` successfully uses the "/xhr/index.mjs" path!
**file included:** `xhr/index.mjs` ✅
Though, its [comment section](https://github.com/evanw/esbuild/blob/f4cec94deaa61e5bb9bd3c0d14ad37ead1d8ca55/internal/resolver/resolver.go#L26-L33) references to an unresolved webpack issue ([webpack/webpack#4674](https://github.com/webpack/webpack/issues/4674)) as the guidance for the implementation - that has changed direction already. esbuild might then eventually move towards the latest webpack implementation and fail on this aspect as others do.
## Using `rollup`
```
cd rollup
npm install
npm start
```
**file included:** `node/index.mjs` ❌
```
(!) Plugin node-resolve: preferring built-in module 'https' over local alternative at 'https', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
(!) Plugin node-resolve: preferring built-in module 'http' over local alternative at 'http', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
(!) Plugin node-resolve: preferring built-in module 'url' over local alternative at 'url', pass 'preferBuiltins: false' to disable this behavior or 'preferBuiltins: true' to disable this warning
(!) Unresolved dependencies
https://rollupjs.org/guide/en/#warning-treating-module-as-external-dependency
https (imported by node_modules/httpie/node/index.mjs)
http (imported by node_modules/httpie/node/index.mjs)
url (imported by node_modules/httpie/node/index.mjs)
created output in 223ms
```