Skip to content

Commit f277afd

Browse files
committed
chore: complete
1 parent 805ae0f commit f277afd

File tree

10 files changed

+67
-92
lines changed

10 files changed

+67
-92
lines changed

packages/core/index.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import { preProcessCSS } from './runtime/pre-process-css'
66
import { getVBindVariableListByPath } from './runtime/process-css'
77
import { initOption } from './option'
88
import { getVariable, matchVariable } from './parser'
9-
import { injectCSSVars } from './inject/inject-cssvars'
10-
import { injectCssOnBuild, injectCssOnServer } from './inject/inject-css'
9+
import {
10+
injectCSSVars,
11+
injectCssOnBuild,
12+
injectCssOnServer,
13+
} from './inject'
1114
import type { TMatchVariable } from './parser'
12-
import type { IBundle, Options } from './types'
13-
14-
import type { OutputOptions } from 'rollup'
15+
import type { Options } from './types'
1516

1617
const unplugin = createUnplugin<Options>(
1718
(options: Options = {}): any => {
@@ -22,13 +23,12 @@ const unplugin = createUnplugin<Options>(
2223
)
2324
// 预处理 css 文件
2425
const CSSFileModuleMap = preProcessCSS(userOptions)
25-
let vbindVariableList = new Map<string, TMatchVariable>()
26+
const vbindVariableList = new Map<string, TMatchVariable>()
2627
let isScriptSetup = false
2728
return [
2829
{
2930
name: NAME,
3031
enforce: 'pre',
31-
3232
transformInclude(id: string) {
3333
return filter(id)
3434
},
@@ -38,13 +38,15 @@ const unplugin = createUnplugin<Options>(
3838
if (id.endsWith('.vue')) {
3939
const { descriptor } = parse(code)
4040
isScriptSetup = !!descriptor.scriptSetup
41-
const vbindVariableListByPath = getVBindVariableListByPath(descriptor, id, CSSFileModuleMap)
41+
const {
42+
vbindVariableListByPath,
43+
injectCSSContent,
44+
} = getVBindVariableListByPath(descriptor, id, CSSFileModuleMap, !!userOptions.dev)
4245
const variableName = getVariable(descriptor)
4346
vbindVariableList.set(id, matchVariable(vbindVariableListByPath, variableName))
44-
if (!userOptions.dev) {
45-
// 1.获取当前组件下 importer 的 文件内容
46-
// 2. 注入到 sfc 中,(替换 v-bind-m -> v-bind)
47-
}
47+
48+
if (!userOptions.dev)
49+
code = injectCssOnBuild(code, injectCSSContent, descriptor)
4850
}
4951
return code
5052
} catch (err: unknown) {
@@ -61,7 +63,7 @@ const unplugin = createUnplugin<Options>(
6163
// transform in dev
6264
if (userOptions.dev) {
6365
if (id.endsWith('.vue')) {
64-
const injectRes = injectCSSVars(code, vbindVariableList.get(id), isScriptSetup, userOptions.dev)
66+
const injectRes = injectCSSVars(code, vbindVariableList.get(id), isScriptSetup)
6567
code = injectRes.code
6668
injectRes.vbindVariableList && vbindVariableList.set(id, injectRes.vbindVariableList)
6769
}

packages/core/inject/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './inject-css'
2+
export * from './inject-cssvars'

packages/core/inject/inject-css.ts

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import chalk from 'chalk'
2-
import { outputFile } from 'fs-extra'
1+
import { transformInjectCSS } from '../transform/transfrom-inject-css'
2+
import { parseImports } from '../parser'
3+
import type { SFCDescriptor } from '@vue/compiler-sfc'
34
import type { TMatchVariable } from '../parser'
4-
import type { OutputOptions } from 'rollup'
5-
import type { IBundle } from '../types'
5+
66
// TODO unit test
77
export function injectCssOnServer(
88
code: string,
@@ -14,29 +14,25 @@ export function injectCssOnServer(
1414
return code
1515
}
1616

17-
export async function injectCssOnBuild(
18-
options: OutputOptions,
19-
bundle: IBundle,
20-
vbindVariableList: TMatchVariable) {
21-
const taskList = []
22-
for (const key in bundle) {
23-
if (bundle[key].type === 'asset') {
24-
const goRevoke = async() => {
25-
const fileName = bundle[key].fileName
26-
const bufferSource = bundle[key].source
27-
console.log(
28-
chalk.greenBright.bold('✨ : [unplugin-vue-cssvars] start inject cssvars'),
29-
chalk.blueBright.bold(`[${fileName}]`))
30-
console.log(bufferSource)
31-
// vbindVariableList.forEach()
32-
// 写入
33-
await outputFile(`${options.dir}/${fileName}`, bufferSource)
34-
}
35-
const task = new Promise((resolve) => {
36-
resolve(goRevoke())
37-
})
38-
taskList.push(task)
39-
}
40-
}
41-
await Promise.all(taskList)
17+
export function injectCssOnBuild(
18+
code: string,
19+
injectCSSContent: Set<{ content: string, lang: string }>,
20+
descriptor: SFCDescriptor) {
21+
const cssContent = [...injectCSSContent]
22+
let resCode = ''
23+
descriptor.styles && descriptor.styles.forEach((value) => {
24+
resCode = `${resCode}\n<style lang="${value.lang || 'css'}">${transformInjectCSS(value.content, parseImports(value.content).imports)}</style>`
25+
})
26+
cssContent.forEach((value) => {
27+
resCode = `${resCode}\n<style lang="${value.lang}">${transformInjectCSS(value.content, parseImports(value.content).imports)}</style>`
28+
})
29+
code = removeStyleTagsAndContent(code)
30+
return `${code}\n${resCode}`
31+
}
32+
33+
export function removeStyleTagsAndContent(html: string): string {
34+
// 使用正则表达式匹配所有的style标签并替换为空字符串
35+
const newHtml = html.replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, '')
36+
// 使用正则表达式匹配所有的style标签并替换为空字符串
37+
return newHtml.replace(/<style\b[^>]*>/gi, '').replace(/<\/style>/gi, '')
4238
}

packages/core/inject/inject-cssvars.ts

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ export const injectCSSVars = (
99
code: string,
1010
vbindVariableList: TMatchVariable | undefined,
1111
isScriptSetup: boolean,
12-
isDev = true,
1312
) => {
1413
if (!vbindVariableList || vbindVariableList.length === 0) return { code, vbindVariableList }
15-
16-
if (isDev)
17-
return injectCSSVarsOnServer(code, vbindVariableList, isScriptSetup)
18-
else
19-
return injectCSSVarsOnBuild(code, vbindVariableList, isScriptSetup)
14+
return injectCSSVarsOnServer(code, vbindVariableList, isScriptSetup)
2015
}
2116

2217
// TODO unit test
@@ -60,46 +55,6 @@ export function injectCSSVarsOnServer(
6055
return { code: resCode, vbindVariableList }
6156
}
6257

63-
export function injectCSSVarsOnBuild(
64-
code: string,
65-
vbindVariableList: TMatchVariable,
66-
isScriptSetup: boolean) {
67-
let resCode = ''
68-
const hasUseCssVars = code.includes('useCssVars')
69-
const useCssVars = createUseCssVarsCode(code, vbindVariableList, hasUseCssVars, isScriptSetup)
70-
if (isScriptSetup) {
71-
// setup script
72-
if (!hasUseCssVars) {
73-
(resCode = code.replaceAll(
74-
'setup(__props) {',
75-
`setup(__props) {${useCssVars}`,
76-
))
77-
resCode = `${importer}${resCode}`
78-
} else {
79-
resCode = useCssVars
80-
}
81-
} else {
82-
// option api
83-
if (!hasUseCssVars) {
84-
resCode = code.replaceAll('const _sfc_main', 'const __default__')
85-
resCode = resCode.replaceAll(
86-
'function _sfc_render',
87-
`${useCssVars}\n
88-
const __setup__ = __default__.setup
89-
__default__.setup = __setup__
90-
? (props, ctx) => { __injectCSSVars__(); return __setup__(props, ctx) }
91-
: __injectCSSVars__
92-
const _sfc_main = __default__
93-
function _sfc_render`)
94-
resCode = `${importer}${resCode}`
95-
} else {
96-
resCode = useCssVars
97-
}
98-
}
99-
100-
return { code: resCode, vbindVariableList }
101-
}
102-
10358
// TODO unit test
10459
export function createUseCssVarsCode(
10560
code: string,

packages/core/runtime/pre-process-css.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export function createCSSFileModuleMap(files: string[], rootDir: string) {
4242
importer: new Set(),
4343
vBindCode: [],
4444
content: '',
45+
lang: 'css',
4546
})
4647
}
4748
}
@@ -81,6 +82,7 @@ export function createCSSFileModuleMap(files: string[], rootDir: string) {
8182
})
8283
cssF.vBindCode = parseVBindM(code)
8384
cssF.content = code
85+
cssF.lang = fileSuffix.replaceAll('.', '')
8486
cssFiles.set(absoluteFilePath, cssF)
8587
}
8688
return cssFiles

packages/core/runtime/process-css.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ export const getCSSFileRecursion = (
3434
export const getVBindVariableListByPath = (
3535
descriptor: SFCDescriptor,
3636
id: string,
37-
cssFiles: ICSSFileMap) => {
37+
cssFiles: ICSSFileMap,
38+
dev: boolean) => {
3839
const vbindVariable: Set<string> = new Set()
40+
const injectCSSContent = new Set<{ content: string, lang: string }>()
3941
// 遍历 sfc 的 style 标签内容
4042
for (let i = 0; i < descriptor.styles.length; i++) {
4143
const content = descriptor.styles[i].content
@@ -54,12 +56,16 @@ export const getVBindVariableListByPath = (
5456
// 根据 @import 信息,从 cssFiles 中,递归的获取所有在预处理时生成的 cssvars 样式
5557
getCSSFileRecursion(key, cssFiles, (res: ICSSFile) => {
5658
if (res.vBindCode) {
59+
!dev && injectCSSContent.add({ content: res.content, lang: res.lang })
5760
res.vBindCode.forEach((vb) => {
5861
vbindVariable.add(vb)
5962
})
6063
}
6164
})
6265
})
6366
}
64-
return setTArray(vbindVariable)
67+
return {
68+
vbindVariableListByPath: setTArray(vbindVariable),
69+
injectCSSContent,
70+
}
6571
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import MagicString from 'magic-string'
2+
import type { ImportStatement } from '../parser'
3+
// TODO: unit test
4+
export function transformInjectCSS(code: string, importer: Array<ImportStatement>) {
5+
const mgc = new MagicString(code)
6+
importer.forEach((imp) => {
7+
mgc.overwrite(imp.start!, imp.end!, '')
8+
})
9+
return mgc.toString()
10+
.replaceAll('@import ;', '')
11+
.replaceAll('v-bind-m', 'v-bind')
12+
}

packages/core/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export interface ICSSFile {
4242
importer: Set<string>
4343
vBindCode: Array<string> | null
4444
content: string
45+
lang: string
4546
}
4647
export declare type ICSSFileMap = Map<string, ICSSFile>
4748
export declare type VariableName = Record<string, Node | undefined | null>

play/src/App.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,4 @@ div {
8787
color: v-bind(color)
8888
}
8989
@import './assets/scss/foo.scss';
90-
9190
</style>

play/vite.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default defineConfig({
2929
viteVueCSSVars({
3030
include: [/.vue/],
3131
includeCompile: ['**/**.scss'],
32-
dev: true,
32+
dev: false,
3333
}),
3434
],
3535
})

0 commit comments

Comments
 (0)