Skip to content

fix: prevent accidental pollution of svelteconfig.extensions #1171

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

Merged
merged 1 commit into from
Jul 11, 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 .changeset/great-corners-spend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': patch
---

fix: prevent accidental pollution of `svelteconfig.extensions`
29 changes: 29 additions & 0 deletions packages/e2e-tests/_test_dependencies/vite-plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export function writeResolvedConfig() {
if (value instanceof RegExp) return value.toString();
else return value;
}

// Handle config from svelte.config.js through vite-plugin-svelte
const vps = config.plugins.find((p) => p.name === 'vite-plugin-svelte');
const configFileOptions = vps?.api?.options;

const serializableConfig = {
...config,
plugins: config.plugins.map((p) => p.name)
Expand All @@ -66,7 +71,31 @@ export function writeResolvedConfig() {
fs.mkdirSync(dir);
}
const filename = path.join(dir, `vite.config.${cmd}${config.build.ssr ? '.ssr' : ''}.json`);
const optionsFilename = path.join(
dir,
`svelte.options.${cmd}${config.build.ssr ? '.ssr' : ''}.json`
);
fs.writeFileSync(filename, JSON.stringify(serializableConfig, replacer, '\t'), 'utf-8');
fs.writeFileSync(optionsFilename, JSON.stringify(configFileOptions, replacer, '\t'), 'utf-8');
}
};
}

/**
* write resolved config
* @returns {import('vite').Plugin}
*/
export function pushToOptimizeDepsExtensions() {
return {
name: 'push-to-optimize-deps-extensions',
config(config) {
if (!config.optimizeDeps) {
config.optimizeDeps = {};
}
if (!config.optimizeDeps.extensions) {
config.optimizeDeps.extensions = [];
}
config.optimizeDeps.extensions.push('.pushed');
}
};
}
24 changes: 24 additions & 0 deletions packages/e2e-tests/kit-node/__tests__/kit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,30 @@ describe('kit-node', () => {
});
});

describe('resolved options', () => {
it('should not be polluted by other plugins pushing to extensions', async () => {
const configs = [];
if (isBuild) {
configs.push('serve', 'build', 'build.ssr');
} else {
configs.push('serve');
}
const expectArrayEqual = (a: string[], b: string[], message: string) => {
const aSorted = a.slice().sort();
const bSorted = b.slice().sort();
expect(aSorted, message).toEqual(bSorted);
};
for (const pattern of configs) {
const filename = `svelte.options.${pattern}.json`;
const config = JSON.parse(
await readFileContent(path.join('logs', 'resolved-configs', filename))
);
const isServe = pattern === 'serve';
expectArrayEqual(['.svelte'], config.extensions, `extensions in ${filename}`);
}
});
});

describe.runIf(isBuild)('output', () => {
it('should produce hermetic build', async () => {
const outputFiles = await glob('./build/**/*', { cwd: testDir, filesOnly: true });
Expand Down
7 changes: 6 additions & 1 deletion packages/e2e-tests/kit-node/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { sveltekit } from '@sveltejs/kit/vite';
import { transformValidation, writeResolvedConfig } from 'e2e-test-dep-vite-plugins';
import {
transformValidation,
writeResolvedConfig,
pushToOptimizeDepsExtensions
} from 'e2e-test-dep-vite-plugins';

/** @type {import('vite').UserConfig} */
export default {
Expand All @@ -16,6 +20,7 @@ export default {
sourcemap: true // must be true for hermetic build test!
},
plugins: [
pushToOptimizeDepsExtensions(),
transformValidation(),
sveltekit(),
writeResolvedConfig(),
Expand Down
2 changes: 1 addition & 1 deletion packages/vite-plugin-svelte/src/utils/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ export async function buildExtraViteConfig(options, config) {
extraViteConfig.optimizeDeps = {
...extraViteConfig.optimizeDeps,
// Experimental Vite API to allow these extensions to be scanned and prebundled
extensions: options.extensions ?? ['.svelte'],
extensions: options.extensions ? [...options.extensions] : ['.svelte'],
// Add esbuild plugin to prebundle Svelte files.
// Currently a placeholder as more information is needed after Vite config is resolved,
// the real Svelte plugin is added in `patchResolvedViteConfig()`
Expand Down
Loading