Skip to content

Commit b875b0c

Browse files
authored
refactor(load-config): remove support for cjs and add support for ts (#1142)
* refactor(load-config): remove support for cjs and add support for ts * fix: replace svelte.config.cjs in tests * fix: remove --experimental-strip-types flag when testing with node20
1 parent bac3e1c commit b875b0c

File tree

11 files changed

+63
-79
lines changed

11 files changed

+63
-79
lines changed

.changeset/nasty-ghosts-warn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/vite-plugin-svelte': major
3+
---
4+
5+
remove support for loading commonjs svelte config files

.changeset/tall-rivers-sleep.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/vite-plugin-svelte': minor
3+
---
4+
5+
add support for loading typescript svelte config files in runtimes that support it

packages/e2e-tests/configfile-custom/__tests__/configfile-custom.spec.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { it, expect } from 'vitest';
22
import { editViteConfig, isBuild, page, e2eServer } from '~utils';
3+
import { versions } from 'node:process';
4+
5+
const isNodeWithoutTypeStripping = Number(versions.node?.split('.', 1)[0]) < 22;
36

47
it('should load default config and work', async () => {
58
expect(e2eServer.logs.server.out).toContain('default svelte config loaded');
@@ -11,11 +14,11 @@ it('should load default config and work', async () => {
1114
if (!isBuild) {
1215
// editing vite config does not work in build tests, build only runs once
1316
// TODO split into different tests
14-
it('should load custom cjs config and work', async () => {
17+
it.skipIf(isNodeWithoutTypeStripping)('should load custom ts config and work', async () => {
1518
await editViteConfig((c) =>
16-
c.replace(/svelte\([^)]*\)/, "svelte({configFile:'svelte.config.custom.cjs'})")
19+
c.replace(/svelte\([^)]*\)/, "svelte({configFile:'svelte.config.custom.ts'})")
1720
);
18-
expect(e2eServer.logs.server.out).toContain('custom svelte config loaded cjs');
21+
expect(e2eServer.logs.server.out).toContain('custom svelte config loaded ts');
1922
expect(await page.textContent('h1')).toMatch('Hello world!');
2023
expect(await page.textContent('#test-child')).toBe('test-child');
2124
expect(await page.textContent('#dependency-import')).toBe('dependency-import');

packages/e2e-tests/configfile-custom/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"private": true,
44
"version": "1.0.0",
55
"scripts": {
6-
"dev": "vite",
7-
"build": "vite build",
6+
"dev": "cross-env NODE_OPTIONS=\"--experimental-strip-types\" vite",
7+
"build": "cross-env NODE_OPTIONS=\"--experimental-strip-types\" vite build",
88
"preview": "vite preview"
99
},
1010
"dependencies": {

packages/e2e-tests/configfile-custom/svelte.config.custom.cjs

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
console.log('custom svelte config loaded ts');
2+
import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte';
3+
const config: SvelteConfig = {
4+
vitePlugin: {
5+
emitCss: false
6+
}
7+
};
8+
export default config;
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
console.log('default svelte config loaded');
2-
module.exports = {};
2+
export default {};

packages/e2e-tests/hmr/__tests__/hmr.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,10 @@ if (!isBuild) {
164164
});
165165

166166
test('should work with emitCss: false in svelte config', async () => {
167-
addFile('svelte.config.cjs', 'module.exports={vitePlugin:{emitCss:false}}');
167+
addFile('svelte.config.js', 'export default {vitePlugin:{emitCss:false}}');
168168
await waitForServerRestartAndPageReload();
169169
expect(await getColor('#hmr-test-1 .label')).toBe('red');
170-
removeFile('svelte.config.cjs');
170+
removeFile('svelte.config.js');
171171
});
172172

173173
test('should detect changes in svelte config and restart', async () => {
@@ -182,8 +182,8 @@ if (!isBuild) {
182182
}
183183
};
184184
await addFile(
185-
'svelte.config.cjs',
186-
`module.exports = {
185+
'svelte.config.js',
186+
`export default {
187187
preprocess:[{markup:${injectPreprocessor.toString()}}]};`
188188
);
189189
await waitForServerRestartAndPageReload();
@@ -196,7 +196,7 @@ if (!isBuild) {
196196
await updateHmrTest((content) => content.replace('color: red', 'color: green'));
197197
expect(await getColor('#hmr-test-1 .label')).toBe('green');
198198
expect(await getText('#hmr-test-1 .counter')).toBe('1');
199-
await editFile('svelte.config.cjs', (content) =>
199+
await editFile('svelte.config.js', (content) =>
200200
content
201201
.replace('preprocess-inject', 'preprocess-inject-2')
202202
.replace('Injected', 'Injected 2')
@@ -212,7 +212,7 @@ if (!isBuild) {
212212
await updateHmrTest((content) => content.replace('color: green', 'color: red'));
213213
expect(await getColor('#hmr-test-1 .label')).toBe('red');
214214
expect(await getText('#hmr-test-1 .counter')).toBe('1');
215-
await removeFile('svelte.config.cjs');
215+
await removeFile('svelte.config.js');
216216
await waitForServerRestartAndPageReload();
217217
expect(await getEl('#preprocess-inject-2')).toBe(null);
218218
expect(await getEl('#preprocess-inject')).toBe(null);

packages/e2e-tests/vitestSetup.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ beforeAll(
145145
if (fs.existsSync(logsDir)) {
146146
fs.rmSync(logsDir, { recursive: true, force: true });
147147
}
148+
// remove strip types flag for node < 22, it doesn't work there
149+
// TODO: remove once node20 is no longer part of CI
150+
if (Number(process.versions.node?.split('.', 1)[0]) < 22) {
151+
const pkgFile = path.join(tempDir, 'package.json');
152+
const pkgContent = fs.readFileSync(pkgFile, 'utf-8');
153+
const newContent = pkgContent.replaceAll(
154+
'cross-env NODE_OPTIONS=\\"--experimental-strip-types\\" ',
155+
''
156+
);
157+
fs.writeFileSync(pkgFile, newContent, 'utf-8');
158+
}
148159
await fs.mkdir(logsDir);
149160
const customServerScript = path.resolve(path.dirname(testPath), 'serve.js');
150161
const defaultServerScript = path.resolve(e2eTestsRoot, 'e2e-server.js');

packages/vite-plugin-svelte/src/utils/load-svelte-config.js

Lines changed: 18 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
1-
import { createRequire } from 'node:module';
21
import path from 'node:path';
32
import process from 'node:process';
43
import fs from 'node:fs';
54
import { pathToFileURL } from 'node:url';
65
import { log } from './log.js';
76

8-
// used to require cjs config in esm.
9-
// NOTE dynamic import() cjs technically works, but timestamp query cache bust
10-
// have no effect, likely because it has another internal cache?
11-
/** @type {NodeRequire}*/
12-
let esmRequire;
13-
14-
export const knownSvelteConfigNames = [
15-
'svelte.config.js',
16-
'svelte.config.cjs',
17-
'svelte.config.mjs'
18-
];
7+
export const knownSvelteConfigNames = ['js', 'ts', 'mjs', 'mts'].map(
8+
(ext) => `svelte.config.${ext}`
9+
);
1910

2011
/**
2112
* @param {string} filePath
@@ -36,56 +27,23 @@ export async function loadSvelteConfig(viteConfig, inlineOptions) {
3627
}
3728
const configFile = findConfigToLoad(viteConfig, inlineOptions);
3829
if (configFile) {
39-
let err;
40-
// try to use dynamic import for svelte.config.js first
41-
if (configFile.endsWith('.js') || configFile.endsWith('.mjs')) {
42-
try {
43-
const result = await dynamicImportDefault(
44-
pathToFileURL(configFile).href,
45-
fs.statSync(configFile).mtimeMs
46-
);
47-
if (result != null) {
48-
return {
49-
...result,
50-
configFile
51-
};
52-
} else {
53-
throw new Error(`invalid export in ${configFile}`);
54-
}
55-
} catch (e) {
56-
log.error(`failed to import config ${configFile}`, e);
57-
err = e;
58-
}
59-
}
60-
// cjs or error with dynamic import
61-
if (!configFile.endsWith('.mjs')) {
62-
try {
63-
// identify which require function to use (esm and cjs mode)
64-
const _require = import.meta.url
65-
? (esmRequire ?? (esmRequire = createRequire(import.meta.url)))
66-
: // eslint-disable-next-line no-undef
67-
require;
68-
69-
// avoid loading cached version on reload
70-
delete _require.cache[_require.resolve(configFile)];
71-
const result = _require(configFile);
72-
if (result != null) {
73-
return {
74-
...result,
75-
configFile
76-
};
77-
} else {
78-
throw new Error(`invalid export in ${configFile}`);
79-
}
80-
} catch (e) {
81-
log.error(`failed to require config ${configFile}`, e);
82-
if (!err) {
83-
err = e;
84-
}
30+
try {
31+
const result = await dynamicImportDefault(
32+
pathToFileURL(configFile).href,
33+
fs.statSync(configFile).mtimeMs
34+
);
35+
if (result != null) {
36+
return {
37+
...result,
38+
configFile
39+
};
40+
} else {
41+
throw new Error(`invalid export in ${configFile}`);
8542
}
43+
} catch (e) {
44+
log.error(`failed to import config ${configFile}`, e);
45+
throw e;
8646
}
87-
// failed to load existing config file
88-
throw err;
8947
}
9048
}
9149

packages/vite-plugin-svelte/types/index.d.ts.map

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@
2626
null,
2727
null
2828
],
29-
"mappings": ";;;;aAIYA,OAAOA;;WAETC,mBAAmBA;;;;;;;;;;;kBAWZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgGbC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiDnBC,mBAAmBA;;;;;;;;;;;;;;;;WAgBnBC,oBAAoBA;;;;;;;;;;;;;;;MAezBC,SAASA;;kBAEGC,qBAAqBA;;;;;;;;;;;;;iBC/JtBC,MAAMA;iBCXNC,cAAcA;iBCORC,gBAAgBA",
29+
"mappings": ";;;;aAIYA,OAAOA;;WAETC,mBAAmBA;;;;;;;;;;;kBAWZC,aAAaA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAgGbC,YAAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAiDnBC,mBAAmBA;;;;;;;;;;;;;;;;WAgBnBC,oBAAoBA;;;;;;;;;;;;;;;MAezBC,SAASA;;kBAEGC,qBAAqBA;;;;;;;;;;;;;iBC/JtBC,MAAMA;iBCXNC,cAAcA;iBCFRC,gBAAgBA",
3030
"ignoreList": []
3131
}

0 commit comments

Comments
 (0)