bun icon indicating copy to clipboard operation
bun copied to clipboard

Bundling (with target: 'bun') outputs code that is incompatible with bun for certain libraries

Open karl-run opened this issue 2 years ago • 6 comments

What version of Bun is running?

1.0.2+37edd5a6e389265738e89265bcbdf2999cb81a49

What platform is your computer?

Linux 6.2.0-32-generic x86_64 x86_64

What steps can reproduce the bug?

  1. Use a library such as gluegun or enquirer
  2. Bundle with target: 'bun'
  3. bun run the output file
55345 |     }
55346 |     path3 = nodePath.normalize(path3);
55347 |     if (appModulePaths.indexOf(path3) === -1) {
55348 |       appModulePaths.push(path3);
55349 | 
55350 |       if (require.main) {
             ^
ReferenceError: Can't find variable: require
      at addPath (/home/karl/git/teamsykmelding-cli/tsm-cli/bin/tsm:55350:10)
      at /home/karl/git/teamsykmelding-cli/tsm-cli/bin/tsm:55456:2
      at /home/karl/git/teamsykmelding-cli/tsm-cli/bin/tsm:38:74
      at /home/karl/git/teamsykmelding-cli/tsm-cli/bin/tsm:70651:29

What is the expected behavior?

Running code directly with bun run, and running it bundled with bun build should both work.

What do you see instead?

It crashes on run, see stack trace above.

Additional information

Code that bundles wrong: https://github.com/navikt/teamsykmelding-cli/blob/feat/sync-file/src/actions/sync-file.ts#L2

Bun.build with target as bun: https://github.com/navikt/teamsykmelding-cli/blob/feat/sync-file/src/build.ts#L4

karl-run avatar Sep 20 '23 13:09 karl-run

Encountering the same issue running Bun 1.0.4 and trying to run a generated application using Fastify.

❯ bun run dist/index.js
37445 |     const display = getDisplayName(func);
37446 |     if (display) {
37447 |       return display;
37448 |     }
37449 | 
37450 |     const cache = require.cache;
                     ^
ReferenceError: Can't find variable: require
      at getPluginName (/home/nezia/dev/sample-fastify-project/dist/index.js:37450:18)
      at override (/home/nezia/dev/sample-fastify-project/dist/index.js:41784:19)
      at /home/nezia/dev/sample-fastify-project/dist/index.js:2934:22
      at loadPlugin (/home/nezia/dev/sample-fastify-project/dist/index.js:2907:4)
      at processTicksAndRejections (:55:76)

Not sure which module is the issue, but these are all the packages I'm using:

"dependencies": {
    "@fastify/cors": "^8.4.0",
    "@prisma/client": "5.2.0",
    "fastify": "^4.22.2"
  },
  "devDependencies": {
    "@faker-js/faker": "^8.1.0",
    "@types/node": "^20.5.9",
    "@typescript-eslint/eslint-plugin": "^6.6.0",
    "@typescript-eslint/parser": "^6.6.0",
    "eslint": "^8.48.0",
    "eslint-config-prettier": "^9.0.0",
    "lint-staged": ">=10",
    "nodemon": "^3.0.1",
    "prettier": "^3.0.3",
    "prisma": "^5.3.1",
    "ts-node": "^10.9.1",
    "typescript": "^5.2.2"
  }

bun build --target=node src/index.ts --outdir=dist works perfectly fine though.

nezia1 avatar Oct 10 '23 10:10 nezia1

Oh this will be tricky. require.cache will be empty. But it doesn’t work because require is not defined and require is not defined because the transpiler is not run again on bundled files. So the question is why doesn’t require.cache get rewritten to import.meta.require.cache, which should at least get past this error

Jarred-Sumner avatar Oct 10 '23 10:10 Jarred-Sumner

Same with bun 1.0.13

Creative-Difficulty avatar Nov 18 '23 16:11 Creative-Difficulty

Unless I'm missing something this impacts a pretty common NAPI pattern like: https://github.com/asilvas/faiss-node/blob/main/lib/index.js#L1

require('bindings')('faiss-napi')

I assumed incorrectly that if you can run bun against typescript fine that when it was transpiled via bun build it would be safe. Only workaround for now is to use target node.

asilvas avatar Nov 29 '23 16:11 asilvas

@asilvas That also doesn't work

Creative-Difficulty avatar Nov 29 '23 18:11 Creative-Difficulty

The bug is that we aren't injecting require into the file. Instead, we are using import.meta.require. We need to inject require at the top of the file like var {require} = import.meta;

Jarred-Sumner avatar Feb 12 '24 04:02 Jarred-Sumner

This also happens with compiled (--compile) files, so bundling and compiling are unusable is the current state.

@Jarred-Sumner The solution you are suggesting seems easy to implement. Are there any gotcha's/drawbacks ?

ishfx avatar Feb 29 '24 09:02 ishfx

Any updates on this? 👀 --compile still doesn't work for me because of ReferenceError: Can't find variable: require.

require.resolve('@bull-board/ui/p[...]

loicnestler avatar Apr 18 '24 20:04 loicnestler