-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathcollect-css-ssr.ts
76 lines (64 loc) · 1.69 KB
/
collect-css-ssr.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
73
74
75
76
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-bitwise */
import type { ModuleNode } from 'vite';
const hashCode = (moduleId: string) => {
let hash = 0;
let i;
let chr;
if (moduleId.length === 0) return hash;
for (i = 0; i < moduleId.length; i += 1) {
chr = moduleId.charCodeAt(i);
hash = (hash << 5) - hash + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
const moduleIsStyle = (mod: ModuleNode) =>
(mod?.file?.endsWith('.scss') ||
mod?.file?.endsWith('.css') ||
mod?.id?.includes('vue&type=style')) &&
mod?.ssrModule;
/**
* Collect SSR CSS for Vite
*/
export const collectCss = (
mods: ModuleNode[] | Set<ModuleNode>,
styles = new Map(),
checkedMods = new Set()
) => {
let result = '';
mods.forEach((mod) => {
if (moduleIsStyle(mod)) {
styles.set(mod.url, mod.ssrModule?.default);
}
if (mod?.importedModules?.size > 0 && !checkedMods.has(mod.id)) {
checkedMods.add(mod.id);
collectCss(mod.importedModules, styles, checkedMods);
}
});
styles.forEach((content, id) => {
result = result.concat(
`<style vite-module-id="${hashCode(id)}">${content}</style>`
);
});
return result;
};
/**
* Client listener to detect updated modules through HMR,
* and remove the initial styled attached to the head
*/
export const removeCssHotReloaded = () => {
if (!import.meta.hot) {
return;
}
import.meta.hot.on('vite:beforeUpdate', (module) => {
module.updates.forEach((update) => {
const moduleStyle = document.querySelector(
`[vite-module-id="${hashCode(update.acceptedPath)}"]`
);
if (moduleStyle) {
moduleStyle.remove();
}
});
});
};