Skip to content

Commit 5c20280

Browse files
authored
fix: Fix bundle variable assignment error with rolldown-vite (#1715)
1 parent bfc8866 commit 5c20280

File tree

3 files changed

+80
-103
lines changed

3 files changed

+80
-103
lines changed

packages/wxt/src/core/builders/vite/index.ts

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type * as vite from 'vite';
22
import {
33
BuildStepOutput,
44
Entrypoint,
5+
EntrypointGroup,
56
ResolvedConfig,
67
WxtBuilder,
78
WxtBuilderServer,
@@ -24,7 +25,9 @@ import { ViteNodeServer } from 'vite-node/server';
2425
import { ViteNodeRunner } from 'vite-node/client';
2526
import { installSourcemapsSupport } from 'vite-node/source-map';
2627
import { createExtensionEnvironment } from '../../utils/environments';
27-
import { relative } from 'node:path';
28+
import { relative, join, extname, dirname } from 'node:path';
29+
import fs from 'fs-extra';
30+
import { normalizePath } from '../../utils/paths';
2831

2932
export async function createViteBuilder(
3033
wxtConfig: ResolvedConfig,
@@ -172,10 +175,7 @@ export async function createViteBuilder(
172175
);
173176
return {
174177
mode: wxtConfig.mode,
175-
plugins: [
176-
wxtPlugins.multipageMove(entrypoints, wxtConfig),
177-
wxtPlugins.entrypointGroupGlobals(entrypoints),
178-
],
178+
plugins: [wxtPlugins.entrypointGroupGlobals(entrypoints)],
179179
build: {
180180
rollupOptions: {
181181
input: entrypoints.reduce<Record<string, string>>((input, entry) => {
@@ -319,9 +319,10 @@ export async function createViteBuilder(
319319
buildConfig,
320320
);
321321
const result = await vite.build(buildConfig);
322+
const chunks = getBuildOutputChunks(result);
322323
return {
323324
entrypoints: group,
324-
chunks: getBuildOutputChunks(result),
325+
chunks: await moveHtmlFiles(wxtConfig, group, chunks),
325326
};
326327
},
327328
async createServer(info) {
@@ -400,3 +401,76 @@ function getRollupEntry(entrypoint: Entrypoint): string {
400401
}
401402
return entrypoint.inputPath;
402403
}
404+
405+
/**
406+
* Ensures the HTML files output by a multipage build are in the correct location. This does two
407+
* things:
408+
*
409+
* 1. Moves the HTML files to their final location at `<outDir>/<entrypoint.name>.html`.
410+
* 2. Updates the bundle so it summarizes the files correctly in the returned build output.
411+
*
412+
* Assets (JS and CSS) are output to the `<outDir>/assets` directory, and don't need to be modified.
413+
* HTML files access them via absolute URLs, so we don't need to update any import paths in the HTML
414+
* files either.
415+
*/
416+
async function moveHtmlFiles(
417+
config: ResolvedConfig,
418+
group: EntrypointGroup,
419+
chunks: BuildStepOutput['chunks'],
420+
): Promise<BuildStepOutput['chunks']> {
421+
if (!Array.isArray(group)) return chunks;
422+
423+
const entryMap = group.reduce<Record<string, Entrypoint>>((map, entry) => {
424+
const a = normalizePath(relative(config.root, entry.inputPath));
425+
map[a] = entry;
426+
return map;
427+
}, {});
428+
429+
const movedChunks = await Promise.all(
430+
chunks.map(async (chunk) => {
431+
if (!chunk.fileName.endsWith('.html')) return chunk;
432+
433+
const entry = entryMap[chunk.fileName];
434+
const oldBundlePath = chunk.fileName;
435+
const newBundlePath = getEntrypointBundlePath(
436+
entry,
437+
config.outDir,
438+
extname(chunk.fileName),
439+
);
440+
const oldAbsPath = join(config.outDir, oldBundlePath);
441+
const newAbsPath = join(config.outDir, newBundlePath);
442+
await fs.ensureDir(dirname(newAbsPath));
443+
await fs.move(oldAbsPath, newAbsPath, { overwrite: true });
444+
445+
return {
446+
...chunk,
447+
fileName: newBundlePath,
448+
};
449+
}),
450+
);
451+
452+
// TODO: Optimize and only delete old path directories
453+
removeEmptyDirs(config.outDir);
454+
455+
return movedChunks;
456+
}
457+
458+
/**
459+
* Recursively remove all directories that are empty/
460+
*/
461+
export async function removeEmptyDirs(dir: string): Promise<void> {
462+
const files = await fs.readdir(dir);
463+
for (const file of files) {
464+
const filePath = join(dir, file);
465+
const stats = await fs.stat(filePath);
466+
if (stats.isDirectory()) {
467+
await removeEmptyDirs(filePath);
468+
}
469+
}
470+
471+
try {
472+
await fs.rmdir(dir);
473+
} catch {
474+
// noop on failure - this means the directory was not empty.
475+
}
476+
}

packages/wxt/src/core/builders/vite/plugins/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
export * from './devHtmlPrerender';
22
export * from './devServerGlobals';
33
export * from './download';
4-
export * from './multipageMove';
54
export * from './resolveVirtualModules';
65
export * from './tsconfigPaths';
76
export * from './noopBackground';

packages/wxt/src/core/builders/vite/plugins/multipageMove.ts

Lines changed: 0 additions & 96 deletions
This file was deleted.

0 commit comments

Comments
 (0)