fix(bundler): allow reactFastRefresh Bun.build option with non-browser targets (#26035)

### What does this PR do?

Previously, reactFastRefresh was silently ignored when target was not
'browser', even when explicitly enabled. This was confusing as there was
no warning or error.

This change removes the `target == .browser` check, trusting explicit
user intent. If users enable reactFastRefresh with a non-browser target,
the transform will now be applied. If `$RefreshReg$` is not defined at
runtime, it will fail fast with a clear error rather than silently doing
nothing.

Use case: Terminal UIs (like [termcast](https://termcast.app)) need
React Fast Refresh with target: 'bun' for hot reloading in non-browser
environments.

### How did you verify your code works?

Updated existing test removing target browser
This commit is contained in:
Tommy D. Rossi
2026-01-14 07:13:17 +01:00
committed by GitHub
parent ab009fe00d
commit af2317deb4
2 changed files with 4 additions and 5 deletions

View File

@@ -1189,8 +1189,7 @@ fn runWithSourceCode(
opts.features.bundler_feature_flags = transpiler.options.bundler_feature_flags;
opts.features.hot_module_reloading = output_format == .internal_bake_dev and !source.index.isRuntime();
opts.features.auto_polyfill_require = output_format == .esm and !opts.features.hot_module_reloading;
opts.features.react_fast_refresh = target == .browser and
transpiler.options.react_fast_refresh and
opts.features.react_fast_refresh = transpiler.options.react_fast_refresh and
loader.isJSX() and
!source.path.isNodeModule();

View File

@@ -4,7 +4,7 @@ import { expect, test } from "bun:test";
import { tempDirWithFiles } from "harness";
import { join } from "path";
test("Bun.build reactFastRefresh option enables React Fast Refresh transform", async () => {
test.each(["browser", "bun"] as const)("Bun.build reactFastRefresh works with target: %s", async (target) => {
const dir = tempDirWithFiles("react-fast-refresh-test", {
"component.tsx": `
import { useState } from "react";
@@ -24,7 +24,7 @@ test("Bun.build reactFastRefresh option enables React Fast Refresh transform", a
const buildEnabled = await Bun.build({
entrypoints: [join(dir, "component.tsx")],
reactFastRefresh: true,
target: "browser",
target,
external: ["react"],
});
@@ -38,7 +38,7 @@ test("Bun.build reactFastRefresh option enables React Fast Refresh transform", a
// Without reactFastRefresh (default), output should NOT contain refresh calls
const buildDisabled = await Bun.build({
entrypoints: [join(dir, "component.tsx")],
target: "browser",
target,
external: ["react"],
});