|
1 | 1 | import type { Plugin } from 'vite'
|
2 |
| -import { parse } from '@vue/compiler-sfc' |
| 2 | +import type { Options } from './type' |
| 3 | +import vueStyleInTemplate from './plugin' |
3 | 4 |
|
4 |
| -export default function vitePluginVueStyleInTemplate(): Plugin { |
| 5 | +export default function vitePluginVueStyleInTemplate(options: Options = {}): Plugin { |
5 | 6 | return {
|
6 | 7 | name: 'vite-plugin-vue-style-in-template',
|
7 | 8 | enforce: 'pre',
|
8 |
| - transform(code: string, id: string) { |
9 |
| - // 只处理 .vue 文件 |
10 |
| - if (!id.endsWith('.vue')) |
11 |
| - return null |
12 |
| - |
13 |
| - const { descriptor } = parse(code) |
14 |
| - |
15 |
| - if (!descriptor.template) |
16 |
| - return null |
17 |
| - |
18 |
| - const templateContent = descriptor.template.content |
19 |
| - const styleRegex = /<style([^>]*)>([\s\S]*?)<\/style>/g |
20 |
| - let noScopedStyles = '' |
21 |
| - let scopedStyles = '' |
22 |
| - |
23 |
| - const newTemplateContent = templateContent.replace(styleRegex, (_, attributes: string, styleContent: string) => { |
24 |
| - if (attributes.includes('scoped')) { |
25 |
| - scopedStyles += `${styleContent}\n` |
26 |
| - } |
27 |
| - else { |
28 |
| - noScopedStyles += `${styleContent}\n` |
29 |
| - } |
30 |
| - return '' |
31 |
| - }) |
32 |
| - |
33 |
| - if (!noScopedStyles && !scopedStyles) |
34 |
| - return null |
35 |
| - |
36 |
| - // 构建新的代码 |
37 |
| - let newCode = code |
38 |
| - |
39 |
| - // 更新 template 内容 |
40 |
| - if (descriptor.template) { |
41 |
| - newCode = newCode.replace( |
42 |
| - descriptor.template.content, |
43 |
| - newTemplateContent, |
44 |
| - ) |
45 |
| - } |
46 |
| - |
47 |
| - // 如果已经存在 style 标签 |
48 |
| - if (descriptor.styles.length > 0) { |
49 |
| - descriptor.styles.forEach((style) => { |
50 |
| - if (style.attrs.scoped && scopedStyles) { |
51 |
| - newCode = newCode.replace( |
52 |
| - style.content, |
53 |
| - `${style.content}\n${scopedStyles}`, |
54 |
| - ) |
55 |
| - scopedStyles = '' |
56 |
| - } |
57 |
| - else if (!style.attrs.scoped && noScopedStyles) { |
58 |
| - newCode = newCode.replace( |
59 |
| - style.content, |
60 |
| - `${style.content}\n${noScopedStyles}`, |
61 |
| - ) |
62 |
| - noScopedStyles = '' |
63 |
| - } |
64 |
| - }) |
65 |
| - } |
66 |
| - |
67 |
| - if (scopedStyles) { |
68 |
| - newCode += `\n<style scoped>\n${scopedStyles}</style>` |
69 |
| - } |
70 |
| - else if (noScopedStyles) { |
71 |
| - newCode += `\n<style>\n${noScopedStyles}</style>` |
72 |
| - } |
73 |
| - |
74 |
| - return { |
75 |
| - code: newCode, |
76 |
| - map: null, |
| 9 | + configResolved(config) { |
| 10 | + // 将当前插件插入到 vite:vue 之前 |
| 11 | + const index = config.plugins.findIndex(p => p && p.name === 'vite:vue') |
| 12 | + if (index !== -1) { |
| 13 | + (config.plugins as Plugin[]).splice(index, 0, vueStyleInTemplate(options)) |
77 | 14 | }
|
78 | 15 | },
|
79 | 16 | }
|
|
0 commit comments