Skip to content

Commit 113bb7d

Browse files
authored
feat: reduce use of cache in vite-plugin-svelte (#32)
1 parent 46c2750 commit 113bb7d

File tree

6 files changed

+56
-88
lines changed

6 files changed

+56
-88
lines changed

.changeset/eight-taxis-wash.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+
Reduced cache usage, share css cache between SSR and client

packages/vite-plugin-svelte/src/handleHotUpdate.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { ModuleNode, HmrContext } from 'vite';
2-
import { CompileData } from './utils/compile';
2+
import { Code, CompileData } from './utils/compile';
33
import { log } from './utils/log';
44
import { SvelteRequest } from './utils/id';
55
import { VitePluginSvelteCache } from './utils/VitePluginSvelteCache';
6+
import { ResolvedOptions } from './utils/options';
67

78
/**
89
* Vite-specific HMR handling
@@ -11,34 +12,33 @@ export async function handleHotUpdate(
1112
compileSvelte: Function,
1213
ctx: HmrContext,
1314
svelteRequest: SvelteRequest,
14-
cache: VitePluginSvelteCache
15+
cache: VitePluginSvelteCache,
16+
options: Partial<ResolvedOptions>
1517
): Promise<ModuleNode[] | void> {
1618
const { read, server } = ctx;
17-
const cachedCompileData = cache.getCompileData(svelteRequest, false);
18-
if (!cachedCompileData) {
19+
20+
const cachedJS = cache.getJS(svelteRequest);
21+
if (!cachedJS) {
1922
// file hasn't been requested yet (e.g. async component)
2023
log.debug(`handleHotUpdate first call ${svelteRequest.id}`);
2124
return;
2225
}
26+
const cachedCss = cache.getCSS(svelteRequest);
2327

2428
const content = await read();
25-
const compileData: CompileData = await compileSvelte(
26-
svelteRequest,
27-
content,
28-
cachedCompileData.options
29-
);
30-
cache.setCompileData(compileData);
29+
const compileData: CompileData = await compileSvelte(svelteRequest, content, options);
30+
cache.update(compileData);
3131

3232
const affectedModules = new Set<ModuleNode | undefined>();
3333

3434
const cssModule = server.moduleGraph.getModuleById(svelteRequest.cssId);
3535
const mainModule = server.moduleGraph.getModuleById(svelteRequest.id);
36-
if (cssModule && cssChanged(cachedCompileData, compileData)) {
36+
if (cssModule && cssChanged(cachedCss, compileData.compiled.css)) {
3737
log.debug('handleHotUpdate css changed');
3838
affectedModules.add(cssModule);
3939
}
4040

41-
if (mainModule && jsChanged(cachedCompileData, compileData)) {
41+
if (mainModule && jsChanged(cachedJS, compileData.compiled.js, svelteRequest.filename)) {
4242
log.debug('handleHotUpdate js changed');
4343
affectedModules.add(mainModule);
4444
}
@@ -56,27 +56,27 @@ export async function handleHotUpdate(
5656
return result;
5757
}
5858

59-
function cssChanged(prev: CompileData, next: CompileData): boolean {
60-
return !isCodeEqual(prev.compiled.css?.code, next.compiled.css?.code);
59+
function cssChanged(prev?: Code, next?: Code): boolean {
60+
return !isCodeEqual(prev?.code, next?.code);
6161
}
6262

63-
function jsChanged(prev: CompileData, next: CompileData): boolean {
64-
const prevJs = prev.compiled.js.code;
65-
const nextJs = next.compiled.js.code;
63+
function jsChanged(prev?: Code, next?: Code, filename?: string): boolean {
64+
const prevJs = prev?.code;
65+
const nextJs = next?.code;
6666
const isStrictEqual = isCodeEqual(prevJs, nextJs);
6767
if (isStrictEqual) {
6868
return false;
6969
}
7070
const isLooseEqual = isCodeEqual(normalizeJsCode(prevJs), normalizeJsCode(nextJs));
7171
if (!isStrictEqual && isLooseEqual) {
7272
log.warn(
73-
`ignoring compiler output js change for ${next.filename} as it is equal to previous output after normalization`
73+
`ignoring compiler output js change for ${filename} as it is equal to previous output after normalization`
7474
);
7575
}
7676
return !isLooseEqual;
7777
}
7878

79-
function isCodeEqual(prev: string, next: string): boolean {
79+
function isCodeEqual(prev?: string, next?: string): boolean {
8080
if (!prev && !next) {
8181
return true;
8282
}
@@ -93,7 +93,7 @@ function isCodeEqual(prev: string, next: string): boolean {
9393
* 2) ... maybe more (or less) in the future
9494
* @param code
9595
*/
96-
function normalizeJsCode(code: string): string {
96+
function normalizeJsCode(code?: string): string | undefined {
9797
if (!code) {
9898
return code;
9999
}

packages/vite-plugin-svelte/src/index.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,10 @@ export default function vitePluginSvelte(inlineOptions?: Partial<Options>): Plug
115115
//
116116
if (query.svelte) {
117117
if (query.type === 'style') {
118-
const compileData = cache.getCompileData(svelteRequest, false);
119-
if (compileData?.compiled?.css) {
118+
const css = cache.getCSS(svelteRequest);
119+
if (css) {
120120
log.debug(`load returns css for ${filename}`);
121-
return compileData.compiled.css;
121+
return css;
122122
}
123123
}
124124
}
@@ -183,26 +183,21 @@ export default function vitePluginSvelte(inlineOptions?: Partial<Options>): Plug
183183
}
184184
log.debug('transform', svelteRequest);
185185
const { filename, query } = svelteRequest;
186-
const cachedCompileData = cache.getCompileData(svelteRequest, false);
187186

188187
if (query.svelte) {
189-
// tagged svelte request, use cache
190-
if (query.type === 'style' && cachedCompileData?.compiled?.css) {
191-
log.debug(`transform returns css for ${filename}`);
192-
return cachedCompileData.compiled.css;
188+
if (query.type === 'style') {
189+
const css = cache.getCSS(svelteRequest);
190+
if (css) {
191+
log.debug(`transform returns css for ${filename}`);
192+
return css; // TODO return code arg instead? it's the code from load hook.
193+
}
193194
}
194195
log.error('failed to transform tagged svelte request', svelteRequest);
195196
throw new Error(`failed to transform tagged svelte request for id ${id}`);
196197
}
197-
198-
if (cachedCompileData && !options.disableTransformCache) {
199-
log.debug(`transform returns cached js for ${filename}`);
200-
return cachedCompileData.compiled.js;
201-
}
202-
203-
// first request, compile here
204198
const compileData = await compileSvelte(svelteRequest, code, options);
205-
cache.setCompileData(compileData);
199+
cache.update(compileData);
200+
206201
log.debug(`transform returns compiled js for ${filename}`);
207202
return compileData.compiled.js;
208203
},
@@ -216,7 +211,7 @@ export default function vitePluginSvelte(inlineOptions?: Partial<Options>): Plug
216211
return;
217212
}
218213
log.debug('handleHotUpdate', svelteRequest);
219-
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache);
214+
return handleHotUpdate(compileSvelte, ctx, svelteRequest, cache, options);
220215
},
221216

222217
// eslint-disable-next-line no-unused-vars
Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,27 @@
11
import { SvelteRequest } from './id';
2-
import { CompileData } from './compile';
2+
import { Code, CompileData } from './compile';
33

44
export class VitePluginSvelteCache {
5-
private _compile = new Map<string, CompileData>();
6-
private _compileSSR = new Map<string, CompileData>();
5+
private _css = new Map<string, Code>();
6+
private _js = new Map<string, Code>();
77

8-
private selectCache(ssr: boolean): Map<string, CompileData> {
9-
return ssr ? this._compileSSR : this._compile;
10-
}
11-
12-
public getCompileData(
13-
svelteRequest: SvelteRequest,
14-
errorOnMissing = true
15-
): CompileData | undefined {
16-
const cache = this.selectCache(svelteRequest.ssr);
17-
const id = svelteRequest.normalizedFilename;
18-
if (cache.has(id)) {
19-
return cache.get(id)!;
20-
}
21-
if (errorOnMissing) {
22-
throw new Error(
23-
`${id} has no corresponding entry in the ${svelteRequest.ssr ? 'ssr' : ''}cache. ` +
24-
`This is a @sveltejs/vite-plugin-svelte internal error, please open an issue.`
25-
);
8+
public update(compileData: CompileData) {
9+
const id = compileData.normalizedFilename;
10+
this._css.set(id, compileData.compiled.css);
11+
if (!compileData.ssr) {
12+
// do not cache SSR js
13+
this._js.set(id, compileData.compiled.js);
2614
}
2715
}
2816

29-
public setCompileData(compileData: CompileData) {
30-
const cache = this.selectCache(!!compileData.ssr);
31-
const id = compileData.normalizedFilename;
32-
cache.set(id, compileData);
17+
public getCSS(svelteRequest: SvelteRequest) {
18+
return this._css.get(svelteRequest.normalizedFilename);
3319
}
3420

35-
// TODO accessors by id/url?
36-
// TODO expose on plugin instance?
21+
public getJS(svelteRequest: SvelteRequest) {
22+
if (!svelteRequest.ssr) {
23+
// SSR js isn't cached
24+
return this._js.get(svelteRequest.normalizedFilename);
25+
}
26+
}
3727
}

packages/vite-plugin-svelte/src/utils/compile.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CompileOptions, PreprocessorGroup, Processed, ResolvedOptions } from './options';
1+
import { CompileOptions, PreprocessorGroup, ResolvedOptions } from './options';
22
import { compile, preprocess, walk } from 'svelte/compiler';
33
// @ts-ignore
44
import { createMakeHot } from 'svelte-hmr';
@@ -74,20 +74,11 @@ const _createCompileSvelte = (makeHot: Function, extraPreprocessors: Preprocesso
7474

7575
compiled.js.dependencies = dependencies;
7676

77-
// return everything that was created during preprocess/compile
78-
const result = {
79-
filename,
77+
return {
8078
normalizedFilename,
81-
cssId,
82-
code,
83-
preprocessed,
8479
compiled,
85-
compilerOptions: finalCompilerOptions,
86-
options,
8780
ssr
8881
};
89-
90-
return result;
9182
};
9283

9384
function buildMakeHot(options: ResolvedOptions) {
@@ -142,13 +133,7 @@ export interface Compiled {
142133
}
143134

144135
export interface CompileData {
145-
filename: string;
146136
normalizedFilename: string;
147-
cssId: string;
148-
code: string;
149-
preprocessed?: Processed;
150137
compiled: Compiled;
151-
compilerOptions: CompileOptions;
152-
options: Partial<ResolvedOptions>;
153138
ssr: boolean | undefined;
154139
}

packages/vite-plugin-svelte/src/utils/options.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const knownOptions = new Set([
1111
'compilerOptions',
1212
'preprocess',
1313
'hot',
14-
'disableTransformCache',
1514
'disableCssHmr',
1615
'useVitePreprocess'
1716
]);
@@ -300,12 +299,6 @@ export interface Options {
300299
*/
301300
disableCssHmr?: boolean;
302301

303-
/**
304-
* do not return cached transform data
305-
* @default false
306-
*/
307-
disableTransformCache?: boolean;
308-
309302
/**
310303
* use vite as extra css preprocessor EXPERIMENTAL!
311304
* @default false

0 commit comments

Comments
 (0)