npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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,708

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:

  1. 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
  2. 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