Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Properly detect and reload changed files when using Vite's ?suffix imports #1432

Merged
merged 1 commit into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
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 packages/wxt-demo/src/entrypoints/ui.content/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import 'uno.css';
import './style.css';
import manualStyle from './manual-style.css?inline';

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

async main(ctx) {
const style = document.createElement('style');
style.textContent = manualStyle;
document.head.append(style);

const ui = await createShadowRootUi(ctx, {
name: 'demo-ui',
position: 'inline',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
body {
padding: 2rem;
background-color: blanchedalmond;
}
Original file line number Diff line number Diff line change
Expand Up @@ -359,5 +359,63 @@ describe('Detect Dev Changes', () => {

expect(actual).toEqual(expected);
});

it('should detect changes to import files with `?suffix`', () => {
const importedPath = '/root/utils/shared.css?inline';
const changedPath = '/root/utils/shared.css';
const script1 = fakeContentScriptEntrypoint({
inputPath: '/root/overlay1.content/index.ts',
});
const script2 = fakeContentScriptEntrypoint({
inputPath: '/root/overlay2.ts',
});
const script3 = fakeContentScriptEntrypoint({
inputPath: '/root/overlay3.content/index.ts',
});

const step1: BuildStepOutput = {
entrypoints: script1,
chunks: [
fakeOutputChunk({
moduleIds: [fakeFile(), importedPath],
}),
],
};
const step2: BuildStepOutput = {
entrypoints: script2,
chunks: [
fakeOutputChunk({
moduleIds: [fakeFile(), fakeFile(), fakeFile()],
}),
],
};
const step3: BuildStepOutput = {
entrypoints: script3,
chunks: [
fakeOutputChunk({
moduleIds: [importedPath, fakeFile(), fakeFile()],
}),
],
};

const currentOutput: BuildOutput = {
manifest: fakeManifest(),
publicAssets: [],
steps: [step1, step2, step3],
};
const expected: DevModeChange = {
type: 'content-script-reload',
cachedOutput: {
...currentOutput,
steps: [step2],
},
changedSteps: [step1, step3],
rebuildGroups: [script1, script3],
};

const actual = detectDevChanges([changedPath], currentOutput);

expect(actual).toEqual(expected);
});
});
});
28 changes: 20 additions & 8 deletions packages/wxt/src/core/utils/building/detect-dev-changes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,26 @@
const changes: BuildStepOutput[] = [];
const changedPath = normalizePath(changedFile);

const isChunkEffected = (chunk: OutputFile): boolean =>
// If it's an HTML file with the same path, is is effected because HTML files need to be re-rendered
// - fileName is normalized, relative bundle path, "<entrypoint-name>.html"
(chunk.type === 'asset' &&
changedPath.replace('/index.html', '.html').endsWith(chunk.fileName)) ||
// If it's a chunk that depends on the changed file, it is effected
// - moduleIds are absolute, normalized paths
(chunk.type === 'chunk' && chunk.moduleIds.includes(changedPath));
const isChunkEffected = (chunk: OutputFile): boolean => {
switch (chunk.type) {
// If it's an HTML file with the same path, is is effected because HTML files need to be re-rendered
// - fileName is normalized, relative bundle path, "<entrypoint-name>.html"
case 'asset': {
return changedPath
.replace('/index.html', '.html')
.endsWith(chunk.fileName);
}
// If it's a chunk that depends on the changed file, it is effected
// - moduleIds are absolute, normalized paths
case 'chunk': {
const modulePaths = chunk.moduleIds.map((path) => path.split('?')[0]);
return modulePaths.includes(changedPath);
}
default: {
return false;
}

Check warning on line 155 in packages/wxt/src/core/utils/building/detect-dev-changes.ts

View check run for this annotation

Codecov / codecov/patch

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

Added lines #L154 - L155 were not covered by tests
}
};

for (const step of currentOutput.steps) {
const effectedChunk = step.chunks.find((chunk) => isChunkEffected(chunk));
Expand Down
Loading