diff --git a/crates/rspack_plugin_lazy_compilation/src/module.rs b/crates/rspack_plugin_lazy_compilation/src/module.rs index d1ce2afbbce5..b2eabfa229b5 100644 --- a/crates/rspack_plugin_lazy_compilation/src/module.rs +++ b/crates/rspack_plugin_lazy_compilation/src/module.rs @@ -1,7 +1,7 @@ use std::{path::Path, sync::Arc}; use cow_utils::CowUtils; -use rspack_cacheable::{cacheable, cacheable_dyn}; +use rspack_cacheable::{cacheable, cacheable_dyn, with::Unsupported}; use rspack_collections::Identifiable; use rspack_core::{ impl_module_meta_info, module_namespace_promise, module_update_hash, @@ -45,6 +45,8 @@ pub(crate) struct LazyCompilationProxyModule { pub active: bool, pub data: String, + /// The client field will be refreshed when rspack restart, so this field does not support caching + #[cacheable(with=Unsupported)] pub client: String, } diff --git a/tests/e2e/cases/lazy-compilation/persistent-cache/index.test.ts b/tests/e2e/cases/lazy-compilation/persistent-cache/index.test.ts new file mode 100644 index 000000000000..bebd7bd2ed19 --- /dev/null +++ b/tests/e2e/cases/lazy-compilation/persistent-cache/index.test.ts @@ -0,0 +1,21 @@ +import { expect, test } from "@/fixtures"; + +test("should load success", async ({ page, rspack }) => { + await page.getByText("Click me").click(); + let component_count = await page.getByText("Component").count(); + expect(component_count).toBe(1); + + const responsePromise = page.waitForResponse( + response => + response.url().includes("lazy-compilation-using") && + response.request().method() === "GET", + { timeout: 5000 } + ); + await rspack.reboot(); + await page.reload(); + await responsePromise; + + await page.getByText("Click me").click(); + component_count = await page.getByText("Component").count(); + expect(component_count).toBe(1); +}); diff --git a/tests/e2e/cases/lazy-compilation/persistent-cache/rspack.config.js b/tests/e2e/cases/lazy-compilation/persistent-cache/rspack.config.js new file mode 100644 index 000000000000..c0c0b204a86c --- /dev/null +++ b/tests/e2e/cases/lazy-compilation/persistent-cache/rspack.config.js @@ -0,0 +1,22 @@ +const rspack = require("@rspack/core"); + +/** @type { import('@rspack/core').RspackOptions } */ +module.exports = { + context: __dirname, + entry: { + main: ["./src/component.js", "./src/index.js"] + }, + stats: "none", + mode: "production", + plugins: [new rspack.HtmlRspackPlugin()], + cache: true, + experiments: { + lazyCompilation: true, + cache: { + type: "persistent" + } + }, + devServer: { + hot: true + } +}; diff --git a/tests/e2e/cases/lazy-compilation/persistent-cache/src/component.js b/tests/e2e/cases/lazy-compilation/persistent-cache/src/component.js new file mode 100644 index 000000000000..408baa5aa888 --- /dev/null +++ b/tests/e2e/cases/lazy-compilation/persistent-cache/src/component.js @@ -0,0 +1,3 @@ +const button = document.createElement("button"); +button.textContent = "Component"; +document.body.appendChild(button); diff --git a/tests/e2e/cases/lazy-compilation/persistent-cache/src/index.js b/tests/e2e/cases/lazy-compilation/persistent-cache/src/index.js new file mode 100644 index 000000000000..61d52b78a82d --- /dev/null +++ b/tests/e2e/cases/lazy-compilation/persistent-cache/src/index.js @@ -0,0 +1,3 @@ +const button = document.createElement("button"); +button.textContent = "Click me"; +document.body.appendChild(button); diff --git a/tests/e2e/fixtures/rspack.ts b/tests/e2e/fixtures/rspack.ts index 780b4855c67e..b993ba2dde86 100644 --- a/tests/e2e/fixtures/rspack.ts +++ b/tests/e2e/fixtures/rspack.ts @@ -1,11 +1,18 @@ import path from "node:path"; import type { Fixtures, PlaywrightTestArgs } from "@playwright/test"; -import { type Compiler, type Configuration, rspack } from "@rspack/core"; +import { + type Compiler, + type Configuration, + rspack, + type RspackOptions as RspackConfig +} from "@rspack/core"; import { RspackDevServer } from "@rspack/dev-server"; import WebpackDevServer from "webpack-dev-server"; import type { PathInfoFixtures } from "./pathInfo"; class Rspack { + private wds: boolean; + private config: RspackConfig; projectDir: string; compiler: Compiler; devServer: RspackDevServer | WebpackDevServer; @@ -15,10 +22,12 @@ class Rspack { wds: boolean, handleRspackConfig: (config: Configuration) => Configuration ) { + this.wds = wds; + const configPath = path.resolve(projectDir, "rspack.config.js"); - const config = handleRspackConfig(require(configPath)); + this.config = handleRspackConfig(require(configPath)); delete require.cache[configPath]; - const compiler = rspack(config); + const compiler = rspack(this.config); this.projectDir = projectDir; this.compiler = compiler; @@ -29,7 +38,7 @@ class Rspack { item(); } }); - const DevServerConstructor = wds ? WebpackDevServer : RspackDevServer; + const DevServerConstructor = this.wds ? WebpackDevServer : RspackDevServer; this.devServer = new DevServerConstructor( compiler.options.devServer ?? ({} as any), compiler @@ -46,6 +55,37 @@ class Rspack { this.onDone.push(resolve); }); } + + async reboot() { + await new Promise((res, rej) => { + this.compiler.close(function (err) { + if (err) { + rej(err); + } else { + res(); + } + }); + }); + await this.devServer.stop(); + + const compiler = rspack(this.config); + compiler.hooks.done.tap("rspack_fixture", () => { + const onDone = this.onDone; + this.onDone = []; + for (const item of onDone) { + item(); + } + }); + const DevServerConstructor = this.wds ? WebpackDevServer : RspackDevServer; + this.devServer = new DevServerConstructor( + compiler.options.devServer ?? ({} as any), + compiler + ); + this.compiler = compiler; + + await this.devServer.start(); + await this.waitingForBuild(); + } } export type RspackOptions = {