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

Bun.build always assume "react-jsxdev" even when set "react-jsx" #3768

Open
rizrmd opened this issue Jul 23, 2023 · 11 comments
Open

Bun.build always assume "react-jsxdev" even when set "react-jsx" #3768

rizrmd opened this issue Jul 23, 2023 · 11 comments
Assignees
Labels
bug Something isn't working bundler Something to do with the bundler

Comments

@rizrmd
Copy link

rizrmd commented Jul 23, 2023

What version of Bun is running?

0.7.0

What platform is your computer?

Darwin 22.5.0 arm64 arm

What steps can reproduce the bug?

run:

  await Bun.build({
    entrypoints: ["./index.tsx"],
    outdir: "./build",
    define: { "process.env.NODE_ENV": '"production"' },
  });

make sure to set {jsx: "react-jsx" } in your tsconfig

What is the expected behavior?

You will see the output always use:
jsx_dev_runtime.jsxDEV("div", {

What do you see instead?

instead of
jsx_runtime.jsx("div", {

Additional information

Why bun always use "react-jsxdev" instead of following tsconfig ?

@rizrmd rizrmd added the bug Something isn't working label Jul 23, 2023
@rizrmd rizrmd changed the title Bun.build always assume "react-jsxdev" even when set react-jsx Bun.build always assume "react-jsxdev" even when set "react-jsx" Jul 23, 2023
@robobun robobun added the bundler Something to do with the bundler label Jul 24, 2023
@mnpenner
Copy link

mnpenner commented Nov 4, 2023

This seems to affect bun ./somefile.tsx too (i.e. running it directly)

@Ricki-BumbleDev
Copy link

Same here. I use a custom JSX implementation (@nanoweb/jsx) that doesn't come with a dev runtime, in which case the issue becomes particularly obvious. Only way to make it work currently is to always set BUN_ENV=production or NODE_ENV=production.

@Enalmada
Copy link

Enalmada commented Jan 9, 2024

Unfortunately I couldn't even get it to work by setting NODE_ENV to production. Just before giving up completely on bundling react libraries with Bun, I happened to find that changing external from ['*'] to a manual list of packages in my dependencies works. I hope this helps someone with a workaround and possibly helps narrow down the bug.

  import getExternalDependenciesFromPackageJson from '@enalmada/bun-externals'
  const externalDeps = await getExternalDependenciesFromPackageJson();

  await Bun.build({
    entrypoints: ['./src/client/urql/UrqlWrapper.tsx'],
    outdir: './dist/client',
    target: 'node',
    external: [...externalDeps, './src/client/urql/UrqlWrapper'],
    root: './src/client',
  });

@tonai
Copy link

tonai commented Jan 15, 2024

NODE_ENV should be equal to production when building. It should be the default.
We should not have to add NODE_ENV=production when running bun build.

@jordanbtucker
Copy link

Just ran into this myself. Looks like it was an intentional design decision.

I'm not really sure what's meant by:

We treat "react-jsx" and "react-jsxDEV" identically because it is too easy to auto-import the wrong one.

Seems like we should, at the very least, fix the documentation. But I would prefer if Bun did what its documentation currently says and use jsx when the setting is react-jsx.

@Duc-Developer
Copy link

Duc-Developer commented Jun 23, 2024

Until current version 1.1.16, it seems this error still exists. There is no difference when choosing "react-jsx" vs "react-jsxdev" in my tsconfig.json, they are always compiled as

import {
jsxDEV
} from "react/jsx-dev-runtime";

Screenshot 2024-06-23 at 16 10 51

When I built a package module for react, using jsxDev resulted in an error on the production.
I have a quick solution to this problem. I don't think it's perfect but it is solving my problem. I hope this issue is resolved soon. If anyone has a better solution please let me know. Thanks a lot!

const fs = require('fs').promises;
const build = async () => {
   await Bun.build({
        entrypoints: ['src/index.tsx'],
        outdir: './dist',   // main file: './dist/index.js'
        format: 'esm',
        splitting: false,
        loader: { '.jsx': 'jsx' },
        external: ['react', 'react-dom'],
        sourcemap: 'external',
   });
   
   const bundleContent = await fs.readFile( './dist/index.js', 'utf8');
    const fixedContent = bundleContent
        .replace(/react\/jsx-dev-runtime/g, 'react/jsx-runtime')
        .replace(/jsxDEV/g, 'jsx');
    await fs.writeFile(bundlePath, fixedContent);
};
build();

@PunchlY
Copy link

PunchlY commented Aug 2, 2024

Although the comment is a bit outdated, I found that using "jsx": "react" can avoid strange errors. But the prerequisite is to import it global:

// main.ts
import React from 'hono/jsx';
// The same problem will occur with hono/jsx module
globalThis.React = React;
{
  "compilerOptions": {
    "jsx": "react"
  }
}

@jordanbtucker
Copy link

@PunchlY I'm not sure what errors you're referring to, but this doesn't seem to have anything to do with this issue.

@PunchlY
Copy link

PunchlY commented Aug 3, 2024

@jordanbtucker
Sorry, I didn't figure it out at the beginning that this was not a bun problem, but a hono/jsx problem. I should have raised it under hono/jsx.

russellmcc added a commit to russellmcc/conformal that referenced this issue Nov 3, 2024
@XavierGeerinck
Copy link

XavierGeerinck commented Dec 24, 2024

Until current version 1.1.16, it seems this error still exists. There is no difference when choosing "react-jsx" vs "react-jsxdev" in my tsconfig.json, they are always compiled as

import {
jsxDEV
} from "react/jsx-dev-runtime";

Screenshot 2024-06-23 at 16 10 51

When I built a package module for react, using jsxDev resulted in an error on the production. I have a quick solution to this problem. I don't think it's perfect but it is solving my problem. I hope this issue is resolved soon. If anyone has a better solution please let me know. Thanks a lot!

const fs = require('fs').promises;
const build = async () => {
   await Bun.build({
        entrypoints: ['src/index.tsx'],
        outdir: './dist',   // main file: './dist/index.js'
        format: 'esm',
        splitting: false,
        loader: { '.jsx': 'jsx' },
        external: ['react', 'react-dom'],
        sourcemap: 'external',
   });
   
   const bundleContent = await fs.readFile( './dist/index.js', 'utf8');
    const fixedContent = bundleContent
        .replace(/react\/jsx-dev-runtime/g, 'react/jsx-runtime')
        .replace(/jsxDEV/g, 'jsx');
    await fs.writeFile(bundlePath, fixedContent);
};
build();

After breaking my head on this for > 5 hours, thank you!

Next.js was always complaining (using shared UI package here built with Bun) with TypeError: (0 , s.jsxDEV) is not a function and indeed, in my tsconfig.json it was set to react-jsx. A quick CTRL + SHIFT +F now does indeed show jsxDEV being found in my dist/ folder??

Thus replacing them all with jsx did the trick.

P.S. adapted it to the below:

// Your build script
await Bun.build({ ... });

// Patch the output 
for (const file of await Array.fromAsync(new Glob("dist/**/*.js").scan())) {
    const content = await Bun.file(file).text();
    await Bun.write(file, content.replace(/jsxDEV/g, 'jsx').replace(/react\/jsx-dev-runtime/g, 'react/jsx-runtime'));
}

@tomaspanek
Copy link

I just encountered the same issue. Replacing all occurrences of jsxDEV with jsx unfortunately does not work for React elements with multiple children, which must be rendered through the jsxs function.

My solution was changing the build command in the package.json from the following:

bun run build.ts

To the following:

NODE_ENV=production bun run build.ts

This worked wonders. It might be that Bun does not correctly recognize the production env variable specified in the Bun.build function, and it has to be entered as part of the build command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working bundler Something to do with the bundler
Projects
None yet
Development

No branches or pull requests