Skip to content

Commit 74c7c5c

Browse files
committed
feat: enable optimizer for server environments during dev
1 parent 3119a4b commit 74c7c5c

File tree

3 files changed

+85
-79
lines changed

3 files changed

+85
-79
lines changed

.changeset/spotty-jokes-notice.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+
feat: enable optimizer for server environments during dev

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ export function configure(api, inlineOptions) {
3939
*/
4040
let preOptions;
4141

42+
/**
43+
* @type {unknown}
44+
*/
45+
let extraViteConfig;
46+
4247
/** @type {import('vite').Plugin} */
4348
return {
4449
name: 'vite-plugin-svelte:config',
@@ -57,11 +62,12 @@ export function configure(api, inlineOptions) {
5762

5863
preOptions = await preResolveOptions(inlineOptions, config, configEnv);
5964
// extra vite config
60-
const extraViteConfig = await buildExtraViteConfig(preOptions, config);
65+
extraViteConfig = await buildExtraViteConfig(preOptions, config);
6166
log.debug('additional vite config', extraViteConfig, 'config');
6267
return extraViteConfig;
6368
}
6469
},
70+
6571
configResolved: {
6672
order: 'pre',
6773
handler(config) {
@@ -87,6 +93,12 @@ export function configure(api, inlineOptions) {
8793
ensureConfigEnvironmentConditions(name, config, opts);
8894
// @ts-expect-error the function above should make `resolve.conditions` non-nullable
8995
config.resolve.conditions.push('svelte');
96+
if (config.consumer === 'server' && extraViteConfig?.optimizeDeps) {
97+
// optimizeDeps is not inherited by server environments so return it here
98+
return {
99+
optimizeDeps: extraViteConfig.optimizeDeps
100+
};
101+
}
90102
},
91103

92104
configureServer(server) {

packages/vite-plugin-svelte/src/plugins/setup-optimizer.js

Lines changed: 67 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export function setupOptimizer(api) {
3232
return {
3333
name: 'vite-plugin-svelte:setup-optimizer',
3434
apply: 'serve',
35-
config() {
35+
configEnvironment(_name, config) {
36+
const consumer = config.consumer ?? 'client';
3637
/** @type {import('vite').UserConfig['optimizeDeps']} */
3738
const optimizeDeps = {
3839
// Experimental Vite API to allow these extensions to be scanned and prebundled
@@ -43,43 +44,25 @@ export function setupOptimizer(api) {
4344
// the added plugins are patched in configResolved below
4445
if (rolldownVersion) {
4546
//@ts-ignore rolldown types not finished
47+
4648
optimizeDeps.rollupOptions = {
4749
plugins: [
48-
placeholderRolldownOptimizerPlugin(optimizeSveltePluginName),
49-
placeholderRolldownOptimizerPlugin(optimizeSvelteModulePluginName)
50+
rolldownOptimizerPlugin(api, consumer, true),
51+
rolldownOptimizerPlugin(api, consumer, false)
5052
]
5153
};
5254
} else {
5355
optimizeDeps.esbuildOptions = {
5456
plugins: [
55-
{ name: optimizeSveltePluginName, setup: () => {} },
56-
{ name: optimizeSvelteModulePluginName, setup: () => {} }
57+
eSBuildOptimizerPlugin(api, consumer, true),
58+
eSBuildOptimizerPlugin(api, consumer, false)
5759
]
5860
};
5961
}
6062
return { optimizeDeps };
6163
},
6264
configResolved(c) {
6365
viteConfig = c;
64-
const optimizeDeps = c.optimizeDeps;
65-
if (rolldownVersion) {
66-
const plugins =
67-
// @ts-expect-error not typed
68-
optimizeDeps.rollupOptions?.plugins?.filter((p) =>
69-
[optimizeSveltePluginName, optimizeSvelteModulePluginName].includes(p.name)
70-
) ?? [];
71-
for (const plugin of plugins) {
72-
patchRolldownOptimizerPlugin(plugin, api.options);
73-
}
74-
} else {
75-
const plugins =
76-
optimizeDeps.esbuildOptions?.plugins?.filter((p) =>
77-
[optimizeSveltePluginName, optimizeSvelteModulePluginName].includes(p.name)
78-
) ?? [];
79-
for (const plugin of plugins) {
80-
patchESBuildOptimizerPlugin(plugin, api.options);
81-
}
82-
}
8366
},
8467
async buildStart() {
8568
if (!api.options.prebundleSvelteLibraries) return;
@@ -94,54 +77,72 @@ export function setupOptimizer(api) {
9477
}
9578

9679
/**
97-
* @param {EsbuildPlugin} plugin
98-
* @param {import('../types/options.d.ts').ResolvedOptions} options
80+
* @param {import('../types/plugin-api.d.ts').PluginAPI} api
81+
* @param {'server'|'client'} consumer
82+
* @param {boolean} components
83+
* @return {EsbuildPlugin}
9984
*/
100-
function patchESBuildOptimizerPlugin(plugin, options) {
101-
const components = plugin.name === optimizeSveltePluginName;
85+
function eSBuildOptimizerPlugin(api, consumer, components) {
86+
const name = components ? optimizeSveltePluginName : optimizeSvelteModulePluginName;
10287
const compileFn = components ? compileSvelte : compileSvelteModule;
10388
const statsName = components ? 'prebundle library components' : 'prebundle library modules';
10489
const filter = components ? /\.svelte(?:\?.*)?$/ : /\.svelte\.[jt]s(?:\?.*)?$/;
105-
plugin.setup = (build) => {
106-
if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
90+
const generate = consumer === 'server' ? 'server' : 'client';
10791

108-
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
109-
let statsCollection;
110-
build.onStart(() => {
111-
statsCollection = options.stats?.startCollection(statsName, {
112-
logResult: (c) => c.stats.length > 1
92+
return {
93+
name,
94+
setup(build) {
95+
if (build.initialOptions.plugins?.some((v) => v.name === 'vite:dep-scan')) return;
96+
97+
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
98+
let statsCollection;
99+
build.onStart(() => {
100+
statsCollection = api.options.stats?.startCollection(statsName, {
101+
logResult: (c) => c.stats.length > 1
102+
});
113103
});
114-
});
115-
build.onLoad({ filter }, async ({ path: filename }) => {
116-
const code = readFileSync(filename, 'utf8');
117-
try {
118-
const result = await compileFn(options, { filename, code }, statsCollection);
119-
const contents = result.map
120-
? result.code + '//# sourceMappingURL=' + result.map.toUrl()
121-
: result.code;
122-
return { contents };
123-
} catch (e) {
124-
return { errors: [toESBuildError(e, options)] };
125-
}
126-
});
127-
build.onEnd(() => {
128-
statsCollection?.finish();
129-
});
104+
build.onLoad({ filter }, async ({ path: filename }) => {
105+
const code = readFileSync(filename, 'utf8');
106+
try {
107+
const result = await compileFn(
108+
api.options,
109+
{ filename, code },
110+
generate,
111+
statsCollection
112+
);
113+
const contents = result.map
114+
? result.code + '//# sourceMappingURL=' + result.map.toUrl()
115+
: result.code;
116+
return { contents };
117+
} catch (e) {
118+
return { errors: [toESBuildError(e, api.options)] };
119+
}
120+
});
121+
build.onEnd(() => {
122+
statsCollection?.finish();
123+
});
124+
}
130125
};
131126
}
132127

133128
/**
134-
* @param {RollupPlugin} plugin
135-
* @param {import('../types/options.d.ts').ResolvedOptions} options
129+
* @param {import('../types/plugin-api.d.ts').PluginAPI} api
130+
* @param {'server'|'client'} consumer
131+
* @param {boolean} components
132+
* @return {import('vite').Rollup.Plugin}
136133
*/
137-
function patchRolldownOptimizerPlugin(plugin, options) {
138-
const components = plugin.name === optimizeSveltePluginName;
134+
function rolldownOptimizerPlugin(api, consumer, components) {
135+
const name = components ? optimizeSveltePluginName : optimizeSvelteModulePluginName;
139136
const compileFn = components ? compileSvelte : compileSvelteModule;
140137
const statsName = components ? 'prebundle library components' : 'prebundle library modules';
141138
const includeRe = components ? /^[^?#]+\.svelte(?:[?#]|$)/ : /^[^?#]+\.svelte\.[jt]s(?:[?#]|$)/;
139+
const generate = consumer === 'server' ? 'server' : 'client';
142140
/** @type {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection | undefined} */
143141
let statsCollection;
144-
142+
/**@type {import('vite').Rollup.Plugin}*/
143+
const plugin = {
144+
name
145+
};
145146
plugin.options = (opts) => {
146147
// @ts-expect-error plugins is an array here
147148
const isScanner = opts.plugins.some(
@@ -160,14 +161,14 @@ function patchRolldownOptimizerPlugin(plugin, options) {
160161
*/
161162
async handler(code, filename) {
162163
try {
163-
return await compileFn(options, { filename, code }, statsCollection);
164+
return await compileFn(api.options, { filename, code }, generate, statsCollection);
164165
} catch (e) {
165-
throw toRollupError(e, options);
166+
throw toRollupError(e, api.options);
166167
}
167168
}
168169
};
169170
plugin.buildStart = () => {
170-
statsCollection = options.stats?.startCollection(statsName, {
171+
statsCollection = api.options.stats?.startCollection(statsName, {
171172
logResult: (c) => c.stats.length > 1
172173
});
173174
};
@@ -176,15 +177,17 @@ function patchRolldownOptimizerPlugin(plugin, options) {
176177
};
177178
}
178179
};
180+
return plugin;
179181
}
180182

181183
/**
182184
* @param {import('../types/options.d.ts').ResolvedOptions} options
183185
* @param {{ filename: string, code: string }} input
186+
* @param {'client'|'server'} generate
184187
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
185188
* @returns {Promise<import('../types/compile.d.ts').Code>}
186189
*/
187-
async function compileSvelte(options, { filename, code }, statsCollection) {
190+
async function compileSvelte(options, { filename, code }, generate, statsCollection) {
188191
let css = options.compilerOptions.css;
189192
if (css !== 'injected') {
190193
// TODO ideally we'd be able to externalize prebundled styles too, but for now always put them in the js
@@ -196,7 +199,7 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
196199
...options.compilerOptions,
197200
css,
198201
filename,
199-
generate: 'client'
202+
generate
200203
};
201204

202205
if (compileOptions.hmr && options.emitCss) {
@@ -252,15 +255,16 @@ async function compileSvelte(options, { filename, code }, statsCollection) {
252255
/**
253256
* @param {import('../types/options.d.ts').ResolvedOptions} options
254257
* @param {{ filename: string; code: string }} input
258+
* @param {'client'|'server'} generate
255259
* @param {import('../types/vite-plugin-svelte-stats.d.ts').StatCollection} [statsCollection]
256260
* @returns {Promise<import('../types/compile.d.ts').Code>}
257261
*/
258-
async function compileSvelteModule(options, { filename, code }, statsCollection) {
262+
async function compileSvelteModule(options, { filename, code }, generate, statsCollection) {
259263
const endStat = statsCollection?.start(filename);
260264
const compiled = svelte.compileModule(code, {
261265
dev: options.compilerOptions?.dev ?? true, // default to dev: true because prebundling is only used in dev
262266
filename,
263-
generate: 'client'
267+
generate
264268
});
265269
if (endStat) {
266270
endStat();
@@ -311,21 +315,6 @@ async function svelteMetadataChanged(cacheDir, options) {
311315
return currentSvelteMetadata !== existingSvelteMetadata;
312316
}
313317

314-
/**
315-
*
316-
* @param {string} name
317-
* @returns {import('vite').Rollup.Plugin}
318-
*/
319-
function placeholderRolldownOptimizerPlugin(name) {
320-
return {
321-
name,
322-
options() {},
323-
buildStart() {},
324-
buildEnd() {},
325-
transform: { filter: { id: /^$/ }, handler() {} }
326-
};
327-
}
328-
329318
/**
330319
* @param {import('../types/options.d.ts').ResolvedOptions} options
331320
* @returns {Partial<import('../types/options.d.ts').ResolvedOptions>}

0 commit comments

Comments
 (0)