Skip to content

Commit a6a9125

Browse files
authored
fix: Properly detect and reload changed files when using Vite's ?suffix imports (#1432)
1 parent 1db50ed commit a6a9125

File tree

4 files changed

+87
-8
lines changed

4 files changed

+87
-8
lines changed

packages/wxt-demo/src/entrypoints/ui.content/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import 'uno.css';
22
import './style.css';
3+
import manualStyle from './manual-style.css?inline';
34

45
export default defineContentScript({
56
matches: ['https://*.duckduckgo.com/*'],
67
cssInjectionMode: 'ui',
78

89
async main(ctx) {
10+
const style = document.createElement('style');
11+
style.textContent = manualStyle;
12+
document.head.append(style);
13+
914
const ui = await createShadowRootUi(ctx, {
1015
name: 'demo-ui',
1116
position: 'inline',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
body {
2+
padding: 2rem;
3+
background-color: blanchedalmond;
4+
}

packages/wxt/src/core/utils/building/__tests__/detect-dev-changes.test.ts

+58
Original file line numberDiff line numberDiff line change
@@ -359,5 +359,63 @@ describe('Detect Dev Changes', () => {
359359

360360
expect(actual).toEqual(expected);
361361
});
362+
363+
it('should detect changes to import files with `?suffix`', () => {
364+
const importedPath = '/root/utils/shared.css?inline';
365+
const changedPath = '/root/utils/shared.css';
366+
const script1 = fakeContentScriptEntrypoint({
367+
inputPath: '/root/overlay1.content/index.ts',
368+
});
369+
const script2 = fakeContentScriptEntrypoint({
370+
inputPath: '/root/overlay2.ts',
371+
});
372+
const script3 = fakeContentScriptEntrypoint({
373+
inputPath: '/root/overlay3.content/index.ts',
374+
});
375+
376+
const step1: BuildStepOutput = {
377+
entrypoints: script1,
378+
chunks: [
379+
fakeOutputChunk({
380+
moduleIds: [fakeFile(), importedPath],
381+
}),
382+
],
383+
};
384+
const step2: BuildStepOutput = {
385+
entrypoints: script2,
386+
chunks: [
387+
fakeOutputChunk({
388+
moduleIds: [fakeFile(), fakeFile(), fakeFile()],
389+
}),
390+
],
391+
};
392+
const step3: BuildStepOutput = {
393+
entrypoints: script3,
394+
chunks: [
395+
fakeOutputChunk({
396+
moduleIds: [importedPath, fakeFile(), fakeFile()],
397+
}),
398+
],
399+
};
400+
401+
const currentOutput: BuildOutput = {
402+
manifest: fakeManifest(),
403+
publicAssets: [],
404+
steps: [step1, step2, step3],
405+
};
406+
const expected: DevModeChange = {
407+
type: 'content-script-reload',
408+
cachedOutput: {
409+
...currentOutput,
410+
steps: [step2],
411+
},
412+
changedSteps: [step1, step3],
413+
rebuildGroups: [script1, script3],
414+
};
415+
416+
const actual = detectDevChanges([changedPath], currentOutput);
417+
418+
expect(actual).toEqual(expected);
419+
});
362420
});
363421
});

packages/wxt/src/core/utils/building/detect-dev-changes.ts

+20-8
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,26 @@ function findEffectedSteps(
135135
const changes: BuildStepOutput[] = [];
136136
const changedPath = normalizePath(changedFile);
137137

138-
const isChunkEffected = (chunk: OutputFile): boolean =>
139-
// If it's an HTML file with the same path, is is effected because HTML files need to be re-rendered
140-
// - fileName is normalized, relative bundle path, "<entrypoint-name>.html"
141-
(chunk.type === 'asset' &&
142-
changedPath.replace('/index.html', '.html').endsWith(chunk.fileName)) ||
143-
// If it's a chunk that depends on the changed file, it is effected
144-
// - moduleIds are absolute, normalized paths
145-
(chunk.type === 'chunk' && chunk.moduleIds.includes(changedPath));
138+
const isChunkEffected = (chunk: OutputFile): boolean => {
139+
switch (chunk.type) {
140+
// If it's an HTML file with the same path, is is effected because HTML files need to be re-rendered
141+
// - fileName is normalized, relative bundle path, "<entrypoint-name>.html"
142+
case 'asset': {
143+
return changedPath
144+
.replace('/index.html', '.html')
145+
.endsWith(chunk.fileName);
146+
}
147+
// If it's a chunk that depends on the changed file, it is effected
148+
// - moduleIds are absolute, normalized paths
149+
case 'chunk': {
150+
const modulePaths = chunk.moduleIds.map((path) => path.split('?')[0]);
151+
return modulePaths.includes(changedPath);
152+
}
153+
default: {
154+
return false;
155+
}
156+
}
157+
};
146158

147159
for (const step of currentOutput.steps) {
148160
const effectedChunk = step.chunks.find((chunk) => isChunkEffected(chunk));

0 commit comments

Comments
 (0)