is-bundling-for-browser-or-node
v1.1.1
Published
Uses package.json fields "browser" and "main" to check whether code is bundled for browser or node
Downloads
1,940
Readme
Is bundling for browser or node (?)
Authoring isomorphic packages yourself can be tricky.
When you use a bundler (webpack, rollup, parcel, vite etc.) and import external modules, the bundler reads the package.json
fields to figure out which file it should use.
If your bundler targets a node.js environment, it usually prefers the main
field
If your bundler targets a browser environment, it usually prefers the browser
field (see spec)
There's two scenarios where isomorphism in js becomes especially hairy:
- use other 3rd party isomorphic packages that are served at compile-time (not runtime), but you want to use the package on both server and client
- you want to offer different builds for each environment (browser, node) to avoid polyfilling the native functionality for both environments in the same bundle
One example is when using the cross-fetch
lib. It's isomorphic at bundle time, not runtime.
Read more background here and specifically this one talks about node.js vs. browser packages
Usage
Just import the named exports. The magic happens when your bundler resolves this module itself.
NOTE! The check happens at bundle/build-time, NOT runtime.
import {
isFor,
isForNode,
isForBrowser,
} from "is-bundling-for-browser-or-node";
// If your bundler targets a node.js environment
expect(isFor).toBe("node");
expect(isForNode).toBe(true);
expect(isForBrowser).toBe(false);
// If your bundler targets a browser environment
expect(isFor).toBe("browser");
expect(isForNode).toBe(false);
expect(isForBrowser).toBe(true);
Example with webpack
Here's a common appraoch to building an isomorphic packages where you provide a bundle for each target environment. Here, we force webpack to prefer different import strategies with the target
property.
// webpack.config.js
export default [
// node
{
entry: "./src/index.ts",
target: "node",
output: {
path: path.resolve(__dirname, "dist"),
filename: "myLib.node.js",
library: {
name: "myLib",
type: "umd",
export: "default",
},
},
externals: [nodeExternals()],
},
// browser
{
entry: "./src/index.ts",
target: "web",
output: {
path: path.resolve(__dirname, "dist"),
filename: "myLib.browser.js",
library: {
name: "myLib",
type: "umd",
export: "default",
},
},
},
];
If you for instance want to offer different default settings for each environment, you can use this package to do so without having to split up your source files into two (i.e. you can keep the same entry).
License
MIT License