Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/five-turtles-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/react-rsbuild-plugin": patch
---

Avoid injecting hot update runtime when dev.hmr or dev.liveReload is set to false.
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
packages/web-platform/** @pupiltong
packages/webpack/** @colinaaa @upupming
packages/rspeedy/** @colinaaa @upupming
packages/rspeedy/plugin-react/** @upupming
packages/react/** @hzy @HuJean
packages/react/transform/** @gaoachao
benchmark/react/** @hzy @HuJean
17 changes: 12 additions & 5 deletions packages/rspeedy/plugin-react/src/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ export function applyEntry(
const entries = chain.entryPoints.entries() ?? {}
const isLynx = environment.name === 'lynx'
const isWeb = environment.name === 'web'
const { hmr, liveReload } = environment.config.dev ?? {}
const enabledHMR = isDev && !isWeb && hmr !== false
const enabledLiveReload = isDev && !isWeb && liveReload !== false

chain.entryPoints.clear()

Expand Down Expand Up @@ -116,7 +119,7 @@ export function applyEntry(
import: imports,
filename: mainThreadName,
})
.when(isDev && !isWeb, entry => {
.when(enabledHMR, entry => {
const require = createRequire(import.meta.url)
// use prepend to make sure it does not affect the exports
// from the entry
Expand All @@ -137,7 +140,7 @@ export function applyEntry(
})
// in standalone lazy bundle mode, we do not add
// other entries to avoid wrongly exporting from other entries
.when(isDev && !isWeb, entry => {
.when(enabledHMR, entry => {
Comment thread
HuJean marked this conversation as resolved.
// use prepend to make sure it does not affect the exports
// from the entry
entry
Expand All @@ -146,14 +149,18 @@ export function applyEntry(
layer: LAYERS.BACKGROUND,
import: '@rspack/core/hot/dev-server',
})
// This is aliased in `./refresh.ts`
.prepend({
layer: LAYERS.BACKGROUND,
import: '@lynx-js/webpack-dev-transport/client',
import: '@lynx-js/react/refresh',
})
// This is aliased in `./refresh.ts`
})
.when(enabledHMR || enabledLiveReload, entry => {
// This is aliased in `@lynx-js/rspeedy`
entry
.prepend({
layer: LAYERS.BACKGROUND,
import: '@lynx-js/react/refresh',
import: '@lynx-js/webpack-dev-transport/client',
})
})
.end()
Expand Down
6 changes: 3 additions & 3 deletions packages/rspeedy/plugin-react/test/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1356,8 +1356,8 @@ describe('Config', () => {
"main": {
"filename": ".rspeedy/main/background.js",
"import": [
"@lynx-js/react/refresh",
"@lynx-js/webpack-dev-transport/client",
"@lynx-js/react/refresh",
"@rspack/core/hot/dev-server",
"./fixtures/basic.tsx",
],
Expand Down Expand Up @@ -1406,8 +1406,8 @@ describe('Config', () => {
"main": {
"filename": ".rspeedy/main/background.[contenthash].js",
"import": [
"@lynx-js/react/refresh",
"@lynx-js/webpack-dev-transport/client",
"@lynx-js/react/refresh",
"@rspack/core/hot/dev-server",
"./fixtures/basic.tsx",
],
Expand Down Expand Up @@ -2076,8 +2076,8 @@ describe('Config', () => {
"main": {
"filename": ".rspeedy/main/background.[contenthash:8].js",
"import": [
"@lynx-js/react/refresh",
"@lynx-js/webpack-dev-transport/client",
"@lynx-js/react/refresh",
"@rspack/core/hot/dev-server",
"./src/index.js",
],
Expand Down
153 changes: 153 additions & 0 deletions packages/rspeedy/plugin-react/test/hotUpdate.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// Copyright 2025 The Lynx Authors. All rights reserved.
// Licensed under the Apache License Version 2.0 that can be found in the
// LICENSE file in the root directory of this source tree.
import { describe, expect, test, vi } from 'vitest'

import { createStubRspeedy as createRspeedy } from './createRspeedy.js'

vi.stubEnv('USE_RSPACK', 'true').stubEnv('NODE_ENV', 'development')

describe('hot update', () => {
test('should prepend hot update runtime in development mode', async () => {
const { pluginReactLynx } = await import('../src/pluginReactLynx.js')
const rsbuild = await createRspeedy({
rspeedyConfig: {
plugins: [
pluginReactLynx(),
],
},
})

const [config] = await rsbuild.initConfigs()
expect(config.entry).toMatchInlineSnapshot(`
{
"main": {
"filename": ".rspeedy/main/background.js",
"import": [
"@lynx-js/webpack-dev-transport/client",
"@lynx-js/react/refresh",
"@rspack/core/hot/dev-server",
"./src/index.js",
],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"layer": "react:background",
},
"main__main-thread": {
"filename": ".rspeedy/main/main-thread.js",
"import": [
"<WORKSPACE>/packages/webpack/css-extract-webpack-plugin/runtime/hotModuleReplacement.lepus.cjs",
"./src/index.js",
],
"layer": "react:main-thread",
},
}
`)
})

test('should prepend hot update runtime when liveReload is set to false', async () => {
const { pluginReactLynx } = await import('../src/pluginReactLynx.js')
const rsbuild = await createRspeedy({
rspeedyConfig: {
dev: {
liveReload: false,
},
plugins: [
pluginReactLynx(),
],
},
})

const [config] = await rsbuild.initConfigs()
expect(config.entry).toMatchInlineSnapshot(`
{
"main": {
"filename": ".rspeedy/main/background.js",
"import": [
"@lynx-js/webpack-dev-transport/client",
"@lynx-js/react/refresh",
"@rspack/core/hot/dev-server",
"./src/index.js",
],
"layer": "react:background",
},
"main__main-thread": {
"filename": ".rspeedy/main/main-thread.js",
"import": [
"<WORKSPACE>/packages/webpack/css-extract-webpack-plugin/runtime/hotModuleReplacement.lepus.cjs",
"./src/index.js",
],
"layer": "react:main-thread",
},
}
`)
})

test('should not prepend refresh runtime when hmr is set to false', async () => {
const { pluginReactLynx } = await import('../src/pluginReactLynx.js')
const rsbuild = await createRspeedy({
rspeedyConfig: {
dev: {
hmr: false,
},
plugins: [
pluginReactLynx(),
],
},
})

const [config] = await rsbuild.initConfigs()
expect(config.entry).toMatchInlineSnapshot(`
{
"main": {
"filename": ".rspeedy/main/background.js",
"import": [
"@lynx-js/webpack-dev-transport/client",
"./src/index.js",
],
"layer": "react:background",
},
"main__main-thread": {
"filename": ".rspeedy/main/main-thread.js",
"import": [
"./src/index.js",
],
"layer": "react:main-thread",
},
}
`)
})

test('should not prepend dev runtime when hmr and liveReload is set to false both', async () => {
const { pluginReactLynx } = await import('../src/pluginReactLynx.js')
const rsbuild = await createRspeedy({
rspeedyConfig: {
dev: {
hmr: false,
liveReload: false,
},
plugins: [
pluginReactLynx(),
],
},
})

const [config] = await rsbuild.initConfigs()
expect(config.entry).toMatchInlineSnapshot(`
{
"main": {
"filename": ".rspeedy/main/background.js",
"import": [
"./src/index.js",
],
"layer": "react:background",
},
"main__main-thread": {
"filename": ".rspeedy/main/main-thread.js",
"import": [
"./src/index.js",
],
"layer": "react:main-thread",
},
}
`)
})
})
Loading