Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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/sweet-crabs-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/rspeedy": patch
---

Support `dev.hmr` and `dev.liveReload`.
2 changes: 2 additions & 0 deletions packages/rspeedy/core/etc/rspeedy.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ export function defineConfig(config: Config): Config;
export interface Dev {
assetPrefix?: string | boolean | undefined;
client?: DevClient | undefined;
hmr?: boolean | undefined;
liveReload?: boolean | undefined;
progressBar?: boolean | {
id?: string;
} | undefined;
Expand Down
82 changes: 82 additions & 0 deletions packages/rspeedy/core/src/config/dev/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,88 @@ export interface Dev {
*/
client?: Client | undefined

/**
* Whether to enable Hot Module Replacement (HMR).
*
* @remarks
*
* Defaults to `true`.
*
* By default, Rspeedy uses HMR as the preferred method to update modules. If HMR is disabled or cannot be used in certain scenarios, it will automatically fallback to {@link Dev.liveReload}.
*
* To completely disable both HMR and live reload, set both `dev.hmr` and `dev.liveReload` to `false`. Then, no WebSocket requests will be made to the dev server on the page, and the page will not automatically refresh when file change.
Comment thread
colinaaa marked this conversation as resolved.
Outdated
*
* @example
*
* Disable HMR:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* hmr: false,
* },
* })
* ```
*
* @example
*
* Disable both HMR and live reload:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* hmr: false,
* liveReload: false,
* },
* })
* ```
*/
hmr?: boolean | undefined

/**
* Whether to enable live reload functionality.
*
* Defaults to `true`.
*
* Live reload is used as a fallback when {@link Dev.hmr} is disabled or cannot be used in certain scenarios. When enabled, the page will automatically refresh when source files are changed.
*
* To completely disable both HMR and live reload, set both `dev.hmr` and `dev.liveReload` to `false`. Then, no WebSocket requests will be made to the dev server on the page, and the page will not automatically refresh when file change.
Comment thread
colinaaa marked this conversation as resolved.
Outdated
*
* @example
*
* Disable live reload:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* liveReload: false,
* },
* })
* ```
*
* @example
*
* Disable both HMR and live reload:
*
* ```js
* import { defineConfig } from '@lynx-js/rspeedy'
*
* export default defineConfig({
* dev: {
* hmr: false,
* liveReload: false,
* },
* })
* ```
*/
liveReload?: boolean | undefined

/**
* Watch specified files and directories for changes. When a file change is detected, it can trigger a page reload or restart the dev server.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/rspeedy/core/src/plugins/dev.plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export function pluginDev(
hostname
}&port=${
api.context.devServer?.port
}&pathname=/rsbuild-hmr&hot=true&live-reload=true&protocol=ws`
}&pathname=/rsbuild-hmr&hot=${options?.hmr ?? true}&live-reload=${options?.liveReload ?? true}&protocol=ws`
)
.set(
'@rspack/core/hot/dev-server',
Expand Down
10 changes: 10 additions & 0 deletions packages/rspeedy/core/test/config/dev.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ describe('Config - Dev', () => {
})
})

test('hmr', () => {
assertType<Dev>({ hmr: true })
assertType<Dev>({ hmr: false })
})

test('liveReload', () => {
assertType<Dev>({ liveReload: true })
assertType<Dev>({ liveReload: false })
})

test('watchFiles', () => {
assertType<Dev>({ watchFiles: { paths: '' } })
assertType<Dev>({ watchFiles: { paths: [] } })
Expand Down
82 changes: 82 additions & 0 deletions packages/rspeedy/core/test/plugins/dev.plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,88 @@ describe('Plugins - Dev', () => {
expect(config.output?.publicPath).not.toBe(`http://example.com:${port}`)
})

test('dev.hmr default', async () => {
const rsbuild = await createStubRspeedy({})

const config = await rsbuild.unwrapConfig()

expect(config.resolve?.alias).toHaveProperty(
'@lynx-js/webpack-dev-transport/client',
expect.stringContaining('hot=true'),
)
})

test('dev.hmr: false', async () => {
const rsbuild = await createStubRspeedy({
dev: {
hmr: false,
},
})

const config = await rsbuild.unwrapConfig()

expect(config.resolve?.alias).toHaveProperty(
'@lynx-js/webpack-dev-transport/client',
expect.stringContaining('hot=false'),
)
})

test('dev.hmr: true', async () => {
const rsbuild = await createStubRspeedy({
dev: {
hmr: true,
},
})

const config = await rsbuild.unwrapConfig()

expect(config.resolve?.alias).toHaveProperty(
'@lynx-js/webpack-dev-transport/client',
expect.stringContaining('hot=true'),
)
})

test('dev.liveReload default', async () => {
const rsbuild = await createStubRspeedy({})

const config = await rsbuild.unwrapConfig()

expect(config.resolve?.alias).toHaveProperty(
'@lynx-js/webpack-dev-transport/client',
expect.stringContaining('live-reload=true'),
)
})

test('dev.liveReload: false', async () => {
const rsbuild = await createStubRspeedy({
dev: {
liveReload: false,
},
})

const config = await rsbuild.unwrapConfig()

expect(config.resolve?.alias).toHaveProperty(
'@lynx-js/webpack-dev-transport/client',
expect.stringContaining('live-reload=false'),
)
})

test('dev.liveReload: true', async () => {
const rsbuild = await createStubRspeedy({
dev: {
liveReload: true,
},
})

const config = await rsbuild.unwrapConfig()

expect(config.resolve?.alias).toHaveProperty(
'@lynx-js/webpack-dev-transport/client',
expect.stringContaining('live-reload=true'),
)
})

test('websocketTransport', async () => {
const rsbuild = await createStubRspeedy({
dev: {
Expand Down