Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Importing disabled modules leads to build failure #3367

Closed
jbaiter opened this issue Sep 5, 2023 · 1 comment
Closed

Importing disabled modules leads to build failure #3367

jbaiter opened this issue Sep 5, 2023 · 1 comment

Comments

@jbaiter
Copy link

jbaiter commented Sep 5, 2023

When disabling certain dependencies for a browser environment via the browser field in the package.json (supported in esbuild since 0.5.26, #238), esbuild raises an exception when building code that tries to import from the disabled dependency.

The expected behavior would be that the import succeeds, but resolves to an undefined value that can be checked for in client code. This is how Vite and Rollup handle it.

To reproduce, put this in a directory, run npm install and npm run build:

package.json:

{
  "name": "esbuild-disabled-dep",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
      "build": "esbuild index.js --bundle --outfile=./out.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "esbuild": "^0.19.2"
  },
  "browser": {
    "node-fetch": false
  }
}

index.js:

import nodeFetch from 'node-fetch';

let fetchImpl;
if (typeof fetch !== 'undefined') {
    fetchImpl = fetch;
    console.log('Using browser fetch');
} else  {
    console.log('Using node-fetch');
    fetchImpl = nodeFetch;
}

Or clone https://gist.github.com/jbaiter/e830fb9fd5b2de5bc9d8db341c91bf94

Trying to build the example with npm run build raises this error:

❯ pnpm run build

> esbuild-disabled-dep@1.0.0 build /tmp/esbuild-disabled-dep
> esbuild index.js --bundle --outfile=./out.js

✘ [ERROR] No matching export in "(disabled):node_modules/.pnpm/node-fetch@3.3.2/node_modules/node-fetch/src/index.js" for import "default"

    index.js:1:7:
      1 │ import nodeFetch from 'node-fetch';
        ╵        ~~~~~~~~~

1 error
 ELIFECYCLE  Command failed with exit code 1.
@jbaiter
Copy link
Author

jbaiter commented Sep 10, 2023

Here's a small bespoke plugin that works around this issue:

// esbuild breaks with NOPed imports (via 'browser' field in package.json),
// (See https://github.com/evanw/esbuild/issues/3367). This is a small
// plugin to work around this for the pdiiif dependency.
const disabledDeps = new Set([
  'node-fetch',
  'jsdom',
  'util',
  'events',
  'zlib',
  'prom-client',
  'color-convert',
  'crypto'
]);

const disabledDepsFixerPlugin = {
  name: 'disabled-dep-fix',
  setup(build) {
    const filter = new RegExp(`^(${Array.from(disabledDeps).join('|')})$`);
    // Intercept import paths that are in the set of disabled dependencies and
    // make them have an `undefined` default export
    build.onResolve({ filter }, ({ path }) => {
      return { path, namespace: 'disabled-dep-fix' }
    })

    build.onLoad({ filter: /.*/, namespace: 'disabled-dep-fix' }, () => ({
      contents: 'export default undefined;',
      resolveDir: process.cwd(),
    }));
  },
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant