-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvite-plugin-webcomponent.js
91 lines (80 loc) · 2.4 KB
/
vite-plugin-webcomponent.js
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { createFilter } from '@rollup/pluginutils'
import CleanCss from 'clean-css'
const minifyCss = (parse) => {
const css = parse.body[0].declaration.callee.body.value
const output = new CleanCss().minify(css)
return output.styles.replace(/(\\)/g, '\\u')
}
const splitCss = (css = '') => {
const pattern = /(:root{.+?})/g
const rootVars = Array.from(css.match(pattern) ?? [])
const styleStr = css.replace(pattern, '')
return [rootVars, styleStr]
}
export default function WebComponent(options = {}) {
const virtualModuleId = 'virtual:vite-plugin-webcomponent'
const resolvedVirtualModuleId = '\0' + virtualModuleId
const filter = createFilter(['**/*.css'])
// 内联样式
const inlineStyles = []
// css 变量样式
const varStyles = []
// global 样式
const globalStyles = []
const elementPlus = ['el-popper', 'el-cascader']
return {
name: 'vite-plugin-webcomponent',
enforce: 'post',
apply: 'build',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `export const styles = "${virtualModuleId}"`
}
},
async transform(code, id) {
if (!filter(id)) return
// console.log(id);
const parse = await this.parse(code)
const css = minifyCss(parse)
for (let fileName of elementPlus) {
if (id.includes(fileName)) {
globalStyles.push(css)
return null
}
}
const [vars, styleStr] = splitCss(css)
varStyles.push(...vars)
inlineStyles.push(styleStr)
},
renderChunk(code, _, { entryFileNames }) {
console.log(globalStyles.length)
let varCode = ''
if (/\.js$/.test(entryFileNames)) {
varCode = `
const rootStyle = document.createElement('style')
rootStyle.innerText = \`${[
...varStyles,
...globalStyles
].join(' ')}\`
document.head.append(rootStyle)
`
}
const styleArray = [...inlineStyles, ...globalStyles]
.reduce((acc, cur) => {
acc.push(`(() => \`${cur}\`)()`)
return acc
}, [])
.join(',')
return {
code:
code.replace(new RegExp(`"${virtualModuleId}"`), `[${styleArray}]`) +
varCode
}
}
}
}