fix(cli): invalidate client modules when bundled dependencies change
Quality / quality (ubuntu-latest) (push) Canceled after 0s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
Clintchiz committed 2026-10-01 22:17:11 +05:30
1 parent 62d1dd8bf3
commit ed1d3a59cf
4 files changed
+34 -3

No files matched your search

+1 -1
View File
@@ -325,7 +325,7 @@
},
"packages/cli": {
"name": "@wrnexus/cli",
"version": "0.8.74",
"version": "0.8.75",
"bin": {
"wrnexus": "src/index.ts",
},
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/cli",
"version": "0.8.74",
"version": "0.8.75",
"type": "module",
"main": "src/index.ts",
"exports": {
+8 -1
View File
@@ -344,7 +344,14 @@ export async function runBuild(appRoot: string): Promise<void> {
`WRN-CLIENT-BUNDLE: failed to bundle ${file}\n${browserResult.logs.map(String).join("\n")}`,
);
}
writeFileSync(clientOut, await browserResult.outputs[0]!.text(), "utf8");
// Cache identity must cover bundled dependencies, not only the .wrn source.
// Otherwise a renderer/package update reuses an immutable browser URL.
const browserSource = await browserResult.outputs[0]!.text();
const bundleHash = createHash("sha256").update(browserSource).digest("hex").slice(0, 16);
const bundledClientOut = join(clientModulesDir, `${clientStem}-${bundleHash}.mjs`);
writeFileSync(bundledClientOut, browserSource, "utf8");
clientFiles.set(file, bundledClientOut);
writeFileSync(out, code.replaceAll(clientUrl, `/__wrnexus/client/${basename(bundledClientOut)}`), "utf8");
rmSync(clientEntry, { force: true });
} catch (error) {
compiledFiles.delete(file);
@@ -0,0 +1,24 @@
import {afterAll,expect,test} from "bun:test";
import {mkdirSync,mkdtempSync,readFileSync,readdirSync,rmSync,writeFileSync} from "node:fs";
import {join} from "node:path";
import {runBuild} from "../src/build.ts";
const scratch=join(import.meta.dir,".tmp-client-dependency");
mkdirSync(scratch,{recursive:true});
afterAll(()=>rmSync(scratch,{recursive:true,force:true}));
test("changing a bundled dependency changes the immutable client URL",async()=>{
const root=mkdtempSync(join(scratch,"app-"));
mkdirSync(join(root,"app/pages"),{recursive:true});
writeFileSync(join(root,"package.json"),JSON.stringify({name:"client-cache-fixture"}));
writeFileSync(join(root,"wrnexus.config.ts"),"export default {};\n");
writeFileSync(join(root,"app/pages/index.wrn"),'import {message} from "../message.ts"\npage Home { functions { client function show(){alert(message)} } view { <button type="button" on:click={show()}>Show message</button> } }');
const files:string[]=[];
for(const message of ["first dependency","updated dependency"]){
writeFileSync(join(root,"app/message.ts"),`export const message=${JSON.stringify(message)};`);
await runBuild(root);
const file=readdirSync(join(root,"dist/client")).find(name=>name.startsWith("index-")&&readFileSync(join(root,"dist/client",name),"utf8").includes(message));
expect(file).toBeDefined();
files.push(file!);
expect(readFileSync(join(root,"dist/server.js"),"utf8")).toContain(`/__wrnexus/client/${file}`);
}
expect(files[0]).not.toBe(files[1]);
},120000);