Skip to content

Commit f02a174

Browse files
committed
wip: second day, getting a hang for it
1 parent 7cdc1df commit f02a174

File tree

16 files changed

+765
-194
lines changed

16 files changed

+765
-194
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
console.log('default svelte config loaded');
2+
export default {};

packages/vite-plugin-svelte/src/handle-hot-update.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export async function handleHotUpdate(compileSvelte, ctx, svelteRequest, cache,
2424
const { read, server, modules } = ctx;
2525

2626
const cachedJS = cache.getJS(svelteRequest);
27-
const cachedCss = cache.getCSS(svelteRequest);
27+
const cachedCss = cache.getCSS(svelteRequest.cssId);
2828

2929
const content = await read();
3030
/** @type {import('./types/compile.d.ts').CompileData} */

packages/vite-plugin-svelte/src/index-modular.js

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { config } from './plugins/config.js';
1+
import { configure } from './plugins/configure.js';
22
import { preprocess } from './plugins/preprocess.js';
33
import { compile } from './plugins/compile.js';
4-
import { externalCss } from './plugins/external-css.js';
5-
import { optimize } from './plugins/optimize.js';
4+
import { loadCompiledCss } from './plugins/load-compiled-css.js';
5+
import { setupOptimizer } from './plugins/setup-optimizer.js';
66
import { optimizeModule } from './plugins/optimize-module.js';
77
import { compileModule } from './plugins/compile-module.js';
88
import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
9+
import {loadCustom} from "./plugins/load-custom.js";
910
/**
1011
* returns a list of plugins to handle svelte files
1112
* plugins are named `vite-plugin-svelte:<task>`
@@ -14,14 +15,25 @@ import { svelteInspector } from '@sveltejs/vite-plugin-svelte-inspector';
1415
* @returns {import('vite').Plugin[]}
1516
*/
1617
export function svelte(inlineOptions) {
18+
/** @type {import('./types/plugin-api.js').PluginAPI} */
19+
const api = {
20+
// @ts-expect-error protection against early use
21+
get options(){
22+
throw new Error('must not use configResolved')
23+
},
24+
// @ts-expect-error protection against early use
25+
get getEnvironmentState() {
26+
throw new Error('must not use before configResolved')
27+
}
28+
};
1729
return [
18-
config(inlineOptions), // parse config and put it on api.__internal for the other plugins to use
19-
optimize(), // create optimize plugin
20-
preprocess(), // preprocess .svelte files
21-
compile(), // compile .svelte files
22-
externalCss(), // return vitrual css modules created by compile
23-
optimizeModule(), // create optimize module plugin
24-
compileModule(),// compile module
30+
configure(api,inlineOptions), // parse config and put it on api.__internal for the other plugins to use
31+
setupOptimizer(api), // add optimizer plugins for pre-bundling in development
32+
preprocess(api), // preprocess .svelte files
33+
compile(api), // compile .svelte files
34+
loadCompiledCss(api), // return virtual css modules created by compile
35+
loadCustom(api), // return custom output d
36+
compileModule(api),// compile module
2537
svelteInspector()
2638
];
2739
}

packages/vite-plugin-svelte/src/plugins/config.js

Lines changed: 0 additions & 92 deletions
This file was deleted.
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import process from 'node:process';
2+
import path from 'node:path';
3+
import { log } from '../utils/log.js';
4+
import * as vite from 'vite';
5+
import { knownSvelteConfigNames } from '../utils/load-svelte-config.js';
6+
import { VitePluginSvelteCache } from '../utils/vite-plugin-svelte-cache.js';
7+
import { VitePluginSvelteStats } from '../utils/vite-plugin-svelte-stats.js';
8+
import {
9+
buildExtraViteConfig,
10+
validateInlineOptions,
11+
resolveOptions,
12+
preResolveOptions,
13+
ensureConfigEnvironmentMainFields,
14+
ensureConfigEnvironmentConditions
15+
} from '../utils/options.js';
16+
import {buildIdFilter, buildIdParser} from "../utils/id.js";
17+
import {createCompileSvelte} from "../utils/compile.js";
18+
19+
20+
// @ts-expect-error rolldownVersion
21+
const { version: viteVersion, rolldownVersion, perEnvironmentState } = vite;
22+
23+
/**
24+
* @param {Partial<import('../public.d.ts').Options>} [inlineOptions]
25+
* @param {import('../types/plugin-api.d.ts').PluginAPI} api
26+
* @returns {import('vite').Plugin}
27+
*/
28+
export function configure(api,inlineOptions) {
29+
if (process.env.DEBUG != null) {
30+
log.setLevel('debug');
31+
}
32+
if (rolldownVersion) {
33+
log.warn.once(
34+
`!!! Support for rolldown-vite in vite-plugin-svelte is experimental (rolldown: ${rolldownVersion}, vite: ${viteVersion}) !!!`
35+
);
36+
}
37+
38+
validateInlineOptions(inlineOptions);
39+
40+
/**
41+
* @type {import("../types/options.d.ts").PreResolvedOptions}
42+
*/
43+
let preOptions;
44+
45+
/** @type {import('vite').Plugin} */
46+
return {
47+
name: 'vite-plugin-svelte:config',
48+
// make sure it runs first
49+
enforce: 'pre',
50+
config:{
51+
order: 'pre',
52+
async handler(config, configEnv) {
53+
// setup logger
54+
if (process.env.DEBUG) {
55+
log.setLevel('debug');
56+
} else if (config.logLevel) {
57+
log.setLevel(config.logLevel);
58+
}
59+
60+
preOptions = await preResolveOptions(inlineOptions, config, configEnv);
61+
// extra vite config
62+
const extraViteConfig = await buildExtraViteConfig(preOptions, config);
63+
log.debug('additional vite config', extraViteConfig, 'config');
64+
return extraViteConfig;
65+
}
66+
},
67+
configResolved: {
68+
order: 'pre',
69+
handler(config) {
70+
const options = resolveOptions(preOptions, config);
71+
api.options = options;
72+
api.getEnvironmentState = perEnvironmentState(_env => {
73+
const cache = new VitePluginSvelteCache()
74+
const stats = new VitePluginSvelteStats(cache)
75+
return {cache,stats}
76+
})
77+
api.idFilter = buildIdFilter(options);
78+
79+
api.idParser = buildIdParser(options);
80+
api.compileSvelte = createCompileSvelte();
81+
log.debug('resolved options', api.options, 'config');
82+
}
83+
},
84+
85+
configEnvironment(name, config, opts) {
86+
ensureConfigEnvironmentMainFields(name, config, opts);
87+
// @ts-expect-error the function above should make `resolve.mainFields` non-nullable
88+
config.resolve.mainFields.unshift('svelte');
89+
90+
ensureConfigEnvironmentConditions(name, config, opts);
91+
// @ts-expect-error the function above should make `resolve.conditions` non-nullable
92+
config.resolve.conditions.push('svelte');
93+
},
94+
95+
configureServer(server) {
96+
const { options } = api;
97+
options.server = server;
98+
restartOnSvelteConfigChanges(options)
99+
}
100+
};
101+
}
102+
103+
/**
104+
* @param {import('../types/options.d.ts').ResolvedOptions} options
105+
* @returns {void}
106+
*/
107+
export function restartOnSvelteConfigChanges(options) {
108+
const { server, configFile: svelteConfigFile } = options;
109+
if (!server) {
110+
return;
111+
}
112+
const { watcher, ws } = server;
113+
const { root, server: serverConfig } = server.config;
114+
115+
116+
/** @type {(filename: string) => void} */
117+
const triggerViteRestart = (filename) => {
118+
if (serverConfig.middlewareMode) {
119+
// in middlewareMode we can't restart the server automatically
120+
// show the user an overlay instead
121+
const message =
122+
'Svelte config change detected, restart your dev process to apply the changes.';
123+
log.info(message, filename);
124+
ws.send({
125+
type: 'error',
126+
err: { message, stack: '', plugin: 'vite-plugin-svelte', id: filename }
127+
});
128+
} else {
129+
log.info(`svelte config changed: restarting vite server. - file: ${filename}`);
130+
server.restart();
131+
}
132+
};
133+
134+
// collection of watcher listeners by event
135+
/** @type {Record<string, Function[]>} */
136+
const listenerCollection = {
137+
add: [],
138+
change: [],
139+
unlink: []
140+
};
141+
142+
if (svelteConfigFile !== false) {
143+
// configFile false means we ignore the file and external process is responsible
144+
const possibleSvelteConfigs = knownSvelteConfigNames.map((cfg) => path.join(root, cfg));
145+
/** @type {(filename: string) => void} */
146+
const restartOnConfigAdd = (filename) => {
147+
if (possibleSvelteConfigs.includes(filename)) {
148+
triggerViteRestart(filename);
149+
}
150+
};
151+
152+
/** @type {(filename: string) => void} */
153+
const restartOnConfigChange = (filename) => {
154+
if (filename === svelteConfigFile) {
155+
triggerViteRestart(filename);
156+
}
157+
};
158+
159+
if (svelteConfigFile) {
160+
listenerCollection.change.push(restartOnConfigChange);
161+
listenerCollection.unlink.push(restartOnConfigChange);
162+
} else {
163+
listenerCollection.add.push(restartOnConfigAdd);
164+
}
165+
}
166+
167+
Object.entries(listenerCollection).forEach(([evt, listeners]) => {
168+
if (listeners.length > 0) {
169+
watcher.on(evt, (filename) => listeners.forEach((listener) => listener(filename)));
170+
}
171+
});
172+
}

packages/vite-plugin-svelte/src/plugins/external-css.js

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { log } from '../utils/log.js';
2+
import { SVELTE_VIRTUAL_STYLE_ID_REGEX } from '../utils/constants.js';
3+
4+
const filter = { id: SVELTE_VIRTUAL_STYLE_ID_REGEX };
5+
6+
/**
7+
* @param {import('../types/plugin-api.d.ts').PluginAPI} api
8+
* @returns {import('vite').Plugin}
9+
*/
10+
export function loadCompiledCss({getEnvironmentState}) {
11+
return {
12+
name: 'vite-plugin-svelte:load-compiled-css',
13+
resolveId: {
14+
filter, // same filter in load to ensure minimal work
15+
handler(id) {
16+
log.debug(`resolveId resolved virtual css module ${id}`, undefined, 'resolve');
17+
return id;
18+
}
19+
},
20+
load: {
21+
filter,
22+
async handler(id) {
23+
const {cache} = getEnvironmentState(this);
24+
const cachedCss = cache.getCSS(id);
25+
if (cachedCss) {
26+
const { hasGlobal, ...css } = cachedCss;
27+
if (hasGlobal === false) {
28+
// hasGlobal was added in svelte 5.26.0, so make sure it is boolean false
29+
css.meta ??= {};
30+
css.meta.vite ??= {};
31+
css.meta.vite.cssScopeTo = [id.slice(0,id.lastIndexOf('?')), 'default'];
32+
}
33+
css.moduleType = 'css';
34+
return css;
35+
}
36+
}
37+
}
38+
};
39+
}

0 commit comments

Comments
 (0)