-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
transform-with-vite.ts
72 lines (60 loc) · 2.15 KB
/
transform-with-vite.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import type { PluginContext } from 'rollup';
import type * as vite from 'vite';
import { STYLE_EXTENSIONS } from '../core/render/util.js';
export type TransformHook = (
code: string,
id: string,
ssr?: boolean
) => Promise<vite.TransformResult>;
interface TransformStyleWithViteOptions {
id: string;
source: string;
lang: string;
ssr?: boolean;
viteDevServer?: vite.ViteDevServer;
}
export interface TransformStyleWithVite {
(options: TransformStyleWithViteOptions): Promise<{
code: string;
map: vite.TransformResult['map'];
deps: Set<string>;
} | null>;
}
export function createTransformStyleWithViteFn(
viteConfig: vite.ResolvedConfig
): TransformStyleWithVite {
const viteCSSPlugin = viteConfig.plugins.find(({ name }) => name === 'vite:css');
if (!viteCSSPlugin) throw new Error(`vite:css plugin couldn't be found`);
if (!viteCSSPlugin.transform) throw new Error(`vite:css has no transform() hook`);
const transformCss = viteCSSPlugin.transform as TransformHook;
return async function (
this: PluginContext,
{ id, source, lang, ssr, viteDevServer }: TransformStyleWithViteOptions
) {
if (!STYLE_EXTENSIONS.has(lang)) {
return null; // only preprocess langs supported by Vite
}
// Id must end with valid CSS extension for vite:css to process
const styleId = `${id}?astro&type=style&lang${lang}`;
viteDevServer?.moduleGraph.ensureEntryFromUrl(styleId, ssr, false);
// This function could be called in a custom Vite hook like `handleHotUpdate`
// which doesn't have a context
const ctx = this ?? { addWatchFile: () => {} };
const transformResult = await transformCss.call(ctx, source, styleId, ssr);
// NOTE: only `code` and `map` are returned by vite:css
const { code, map } = transformResult;
const deps = new Set<string>();
// Get deps from module created while transforming the styleId by Vite.
// In build, it's fine that we skip this as it's used by HMR only.
const mod = viteDevServer?.moduleGraph.getModuleById(styleId);
if (mod) {
// Get all @import references
for (const imported of mod.importedModules) {
if (imported.file) {
deps.add(imported.file);
}
}
}
return { code, map, deps };
};
}