oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.13k stars 2.76k forks source link

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

Open karl-run opened 1 year ago

karl-run commented 1 year ago

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

nezia1 commented 1 year ago

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.

Jarred-Sumner commented 1 year ago

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

Creative-Difficulty commented 11 months ago

Same with bun 1.0.13

asilvas commented 11 months ago

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.

Creative-Difficulty commented 11 months ago

@asilvas That also doesn't work

Jarred-Sumner commented 9 months ago

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;

ishfx commented 8 months ago

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 ?

loicnestler commented 6 months ago

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[...]