Skip to content

Commit 488978f

Browse files
authored
fix: path calculation error (#29)
* fix: path calculation error * test: update unit test * test: update catch error info
1 parent b99ef1c commit 488978f

File tree

8 files changed

+79
-46
lines changed

8 files changed

+79
-46
lines changed

packages/core/runtime/__test__/process-css.spec.ts

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ describe('process css', () => {
99
const mockEvt = vi.fn()
1010
const mockRes: Array<ICSSFile> = []
1111
const mockCssFiles = new Map()
12-
mockCssFiles.set('foo', {
12+
mockCssFiles.set('foo.css', {
1313
importer: new Set(),
1414
vBindCode: {
1515
foo: new Set(['v-bind(foo)']),
1616
},
1717
})
18-
getCSSFileRecursion('foo', mockCssFiles, (v) => {
18+
getCSSFileRecursion('css', 'foo', mockCssFiles, (v) => {
1919
mockEvt()
2020
mockRes.push(v)
2121
})
@@ -30,34 +30,56 @@ describe('process css', () => {
3030
const mockEvt = vi.fn()
3131
const mockRes = []
3232
const mockCssFiles = new Map()
33-
mockCssFiles.set('foo', {
33+
mockCssFiles.set('foo.css', {
3434
importer: new Set(['foo1', 'foo2']),
3535
})
36-
getCSSFileRecursion('bar', mockCssFiles, (v) => {
36+
const testFn = () => getCSSFileRecursion('css', 'bar', mockCssFiles, (v) => {
3737
mockEvt()
3838
mockRes.push(v)
3939
})
4040
expect(mockRes.length).toBe(0)
4141
expect(mockEvt).not.toBeCalled()
42+
expect(testFn).toThrowError()
43+
})
44+
45+
test('getCSSFileRecursion: not custom suffix', () => {
46+
const mockEvt = vi.fn()
47+
const mockRes: Array<ICSSFile> = []
48+
const mockCssFiles = new Map()
49+
mockCssFiles.set('foo.module.css', {
50+
importer: new Set(),
51+
vBindCode: {
52+
foo: new Set(['v-bind(foo)']),
53+
},
54+
})
55+
getCSSFileRecursion('css', 'foo.module', mockCssFiles, (v) => {
56+
mockEvt()
57+
mockRes.push(v)
58+
})
59+
expect(mockRes.length).toBe(1)
60+
expect(mockEvt).toBeCalledTimes(1)
61+
expect(mockRes[0].vBindCode).toMatchObject({
62+
foo: new Set(['v-bind(foo)']),
63+
})
4264
})
4365

4466
test('getCSSFileRecursion: recursion', () => {
4567
const mockEvt = vi.fn()
4668
const mockRes: Array<ICSSFile> = []
4769
const mockCssFiles = new Map()
48-
mockCssFiles.set('foo', {
49-
importer: new Set(['bar']),
70+
mockCssFiles.set('foo.css', {
71+
importer: new Set(['bar.css']),
5072
vBindCode: {
5173
foo: new Set(['v-bind(foo)']),
5274
},
5375
})
54-
mockCssFiles.set('bar', {
76+
mockCssFiles.set('bar.css', {
5577
importer: new Set(),
5678
vBindCode: {
5779
bar: new Set(['v-bind(bar)']),
5880
},
5981
})
60-
getCSSFileRecursion('foo', mockCssFiles, (v) => {
82+
getCSSFileRecursion('css', 'foo', mockCssFiles, (v) => {
6183
mockEvt()
6284
mockRes.push(v)
6385
})
@@ -75,19 +97,19 @@ describe('process css', () => {
7597
const mockEvt = vi.fn()
7698
const mockRes: Array<ICSSFile> = []
7799
const mockCssFiles = new Map()
78-
mockCssFiles.set('foo', {
79-
importer: new Set(['bar']),
100+
mockCssFiles.set('foo.css', {
101+
importer: new Set(['bar.css']),
80102
vBindCode: {
81103
foo: new Set(['v-bind(foo)']),
82104
},
83105
})
84-
mockCssFiles.set('bar', {
106+
mockCssFiles.set('bar.css', {
85107
importer: new Set(['foo']),
86108
vBindCode: {
87109
bar: new Set(['v-bind(bar)']),
88110
},
89111
})
90-
getCSSFileRecursion('foo', mockCssFiles, (v) => {
112+
getCSSFileRecursion('css', 'foo', mockCssFiles, (v) => {
91113
mockEvt()
92114
mockRes.push(v)
93115
})

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,14 @@ export function createCSSFileModuleMap(files: string[], rootDir: string) {
6666
fileDirParse.dir,
6767
value.path.replace(/^"|"$/g, ''))
6868
// 默认使用 .css
69-
let importerVal = completeSuffix(importerPath)
69+
let importerVal = completeSuffix(importerPath, SUPPORT_FILE.CSS)
7070
// 如果 file 不是 .css 文件,那么它的 import 需要判断处理
7171
if (fileSuffix !== `.${SUPPORT_FILE.CSS}`) {
72-
// 先根据后缀名查找是否存在该文件
72+
// 根据后缀名查找是否存在该文件
7373
const importerValBySuffix = completeSuffix(
7474
importerPath,
7575
fileSuffix.split('.')[1],
76+
true,
7677
)
7778
// 存在就使用 fileSuffix 的后缀文件
7879
if (cssFiles.get(importerValBySuffix))

packages/core/runtime/process-css.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
import { parse, resolve } from 'path'
22
import { SUPPORT_FILE, completeSuffix, setTArray } from '@unplugin-vue-cssvars/utils'
3-
import chalk from 'chalk'
43
import { parseImports } from '../parser'
54
import type { ICSSFile, ICSSFileMap } from '../types'
65
import type { SFCDescriptor } from '@vue/compiler-sfc'
76

87
export const getCSSFileRecursion = (
8+
lang: string = SUPPORT_FILE.CSS,
99
key: string,
1010
cssFiles: ICSSFileMap,
1111
cb: (res: ICSSFile) => void,
1212
matchedMark = new Set<string>()) => {
13+
// 添加后缀
14+
// sfc中规则:如果@import 指定了后缀,则根据后缀,否则根据当前 script 标签的 lang 属性(默认css)
15+
key = completeSuffix(key, lang)
16+
// 如果 .scss 的 import 不存在,则用 css 的
17+
if (!cssFiles.get(key))
18+
key = completeSuffix(key, SUPPORT_FILE.CSS, true)
19+
1320
// 避免循环引用
1421
if (matchedMark.has(key)) return
1522
const cssFile = cssFiles.get(key)
@@ -18,11 +25,11 @@ export const getCSSFileRecursion = (
1825
cb(cssFile)
1926
if (cssFile.importer.size > 0) {
2027
cssFile.importer.forEach((value) => {
21-
getCSSFileRecursion(value, cssFiles, cb, matchedMark)
28+
getCSSFileRecursion(lang, value, cssFiles, cb, matchedMark)
2229
})
2330
}
2431
} else {
25-
console.log(chalk.yellowBright(`[uplugin-vue-cssvars]: The writing of the path '${key}' is not standardized, which may cause \`v-bind-m\` to fail to take effect`))
32+
throw new Error('path')
2633
}
2734
}
2835

@@ -51,22 +58,25 @@ export const getVBindVariableListByPath = (
5158
const parseImporterRes = parseImports(content)
5259
parseImporterRes.imports.forEach((res) => {
5360
const importerPath = resolve(idDirParse.dir, res.path)
54-
// 添加后缀
55-
// sfc中规则:如果@import 指定了后缀,则根据后缀,否则根据当前 script 标签的 lang 属性(默认css)
56-
let key = completeSuffix(importerPath, lang)
57-
// 如果 .scss 的 import 不存在,则用 css 的
58-
if (!cssFiles.get(key))
59-
key = completeSuffix(importerPath)
6061

61-
// 根据 @import 信息,从 cssFiles 中,递归的获取所有在预处理时生成的 cssvars 样式
62-
getCSSFileRecursion(key, cssFiles, (res: ICSSFile) => {
63-
if (res.vBindCode) {
64-
!server && injectCSSContent.add({ content: res.content, lang: res.lang, styleTagIndex: i })
65-
res.vBindCode.forEach((vb) => {
66-
vbindVariable.add(vb)
67-
})
62+
try {
63+
// 根据 @import 信息,从 cssFiles 中,递归的获取所有在预处理时生成的 cssvars 样式
64+
getCSSFileRecursion(lang, importerPath, cssFiles, (res: ICSSFile) => {
65+
if (res.vBindCode) {
66+
!server && injectCSSContent.add({ content: res.content, lang: res.lang, styleTagIndex: i })
67+
res.vBindCode.forEach((vb) => {
68+
vbindVariable.add(vb)
69+
})
70+
}
71+
})
72+
} catch (e) {
73+
if ((e as Error).message === 'path') {
74+
const doc = 'https://github.com/baiwusanyu-c/unplugin-vue-cssvars/pull/29'
75+
throw new Error(`Unable to resolve file under path '${res.path}', see: ${doc}`)
76+
} else {
77+
throw new Error((e as Error).message)
6878
}
69-
})
79+
}
7080
})
7181
}
7282
return {

play/src/main.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import { createApp } from 'vue'
2-
import App from './App.vue'
2+
import App from './views/app/App.vue'
33
createApp(App).mount('#app')

play/src/App.vue renamed to play/src/views/app/App.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import { reactive, ref } from 'vue'
3-
import Comp from './comp.vue'
3+
import Comp from '../../comp.vue'
44
const color = 'green'
55
const appAsd = () => 'red'
66
const fooColor = appAsd()
@@ -79,8 +79,8 @@ export default defineComponent({
7979
</template>
8080

8181
<style lang="scss" scoped>
82-
@import './assets/scss/mixin.scss';
83-
@import './assets/scss/variables.module.scss';
82+
@import '../src/assets/scss/mixin';
83+
@import '../../assets/scss/variables.module';
8484
/* foo.scss -> test2.css -> test.css */
8585
/* foo.scss -> test.scss -> test2.css */
8686

pnpm-lock.yaml

Lines changed: 2 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

utils/constant.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export const NAME = 'unplugin-vue-cssvars'
22
export const SUPPORT_FILE_LIST = ['**/**.css']
3+
export const SUPPORT_FILE_REG = /\.(css|sass|scss|styl|less)$/i
34
export const FG_IGNORE_LIST = ['**/node_modules/**', '**/dist/**', '**/.git/**']
45
export const SUPPORT_FILE = {
56
CSS: 'css',

utils/index.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { SUPPORT_FILE } from './constant'
2-
1+
import { join, parse } from 'path'
2+
import { SUPPORT_FILE, SUPPORT_FILE_REG } from './constant'
33
export * from './constant'
44

55
export const extend = <
@@ -16,7 +16,11 @@ export const isEmptyObj = (val: unknown) => JSON.stringify(val) === '{}'
1616

1717
export const transformSymbol = (path: string) => path.replaceAll('\\', '/')
1818

19-
export const completeSuffix = (fileName: string, suffix = SUPPORT_FILE.CSS) => {
19+
export const completeSuffix = (fileName: string, suffix: string, force?: boolean) => {
2020
const transformSymbolRes = transformSymbol(fileName)
21-
return !(/\.[^./\\]+$/i.test(transformSymbolRes)) ? `${transformSymbolRes}.${suffix}` : transformSymbolRes
21+
if (force) {
22+
const { dir, name } = parse(transformSymbolRes)
23+
return transformSymbol(join(dir, `${name}.${suffix || SUPPORT_FILE.CSS}`))
24+
}
25+
return !(SUPPORT_FILE_REG.test(transformSymbolRes)) && suffix ? `${transformSymbolRes}.${suffix}` : transformSymbolRes
2226
}

0 commit comments

Comments
 (0)