-
Notifications
You must be signed in to change notification settings - Fork 157
/
Copy pathprocess-style.js
140 lines (125 loc) · 3.41 KB
/
process-style.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
const { compileStyle } = require('@vue/compiler-sfc')
const path = require('path')
const cssTree = require('css-tree')
const getVueJestConfig = require('./utils').getVueJestConfig
const applyModuleNameMapper = require('./module-name-mapper-helper')
const { generateFileId } = require('./utils')
const getCustomTransformer = require('./utils').getCustomTransformer
const logResultErrors = require('./utils').logResultErrors
const loadSrc = require('./utils').loadSrc
function getGlobalResources(resources, lang) {
let globalResources = ''
if (resources && resources[lang]) {
globalResources = resources[lang]
.map(resource => {
// need replace \ to / in windows
const absolutePath = path
.resolve(process.cwd(), resource)
.replaceAll('\\', '/')
return `${getImportLine(lang, absolutePath)}\n`
})
.join('')
}
return globalResources
}
function getImportLine(lang, filePath) {
const importLines = {
default: `@import "${filePath}";`,
sass: `@import "${filePath}"`
}
return importLines[lang] || importLines.default
}
function extractClassMap(cssCode) {
const ast = cssTree.parse(cssCode)
return cssTree
.findAll(ast, node => node.type === 'ClassSelector')
.reduce((acc, cssNode) => {
acc[cssNode.name] = cssNode.name
return acc
}, {})
}
function getPreprocessOptions(lang, filePath, jestConfig) {
if (lang === 'scss' || lang === 'sass') {
return {
filename: filePath,
importer: (url, prev) => ({
file: applyModuleNameMapper(
url,
prev === 'stdin' ? filePath : prev,
jestConfig,
lang
)
})
}
}
if (lang === 'styl' || lang === 'stylus' || lang === 'less') {
return {
paths: [path.dirname(filePath), process.cwd()]
}
}
}
module.exports = function processStyle(stylePart, filePath, config = {}) {
const vueJestConfig = getVueJestConfig(config)
if (stylePart.src && !stylePart.content.trim()) {
const cssFilePath = applyModuleNameMapper(
stylePart.src,
filePath,
config.config,
stylePart.lang
)
stylePart.content = loadSrc(cssFilePath, filePath)
filePath = cssFilePath
}
if (vueJestConfig.experimentalCSSCompile === false || !stylePart.content) {
return '{}'
}
let content =
getGlobalResources(vueJestConfig.resources, stylePart.lang) +
stylePart.content
const transformer =
getCustomTransformer(vueJestConfig['transform'], stylePart.lang) || {}
// pre process
if (transformer.preprocess) {
content = transformer.preprocess(
content,
filePath,
config.config,
stylePart.attrs
)
}
// transform
if (transformer.process) {
content = transformer.process(
content,
filePath,
config.config,
stylePart.attrs
)
} else {
const preprocessOptions = getPreprocessOptions(
stylePart.lang,
filePath,
config.config
)
const result = compileStyle({
id: `vue-jest-${generateFileId(filePath)}`,
source: content,
filePath,
preprocessLang: stylePart.lang,
preprocessOptions,
scoped: false
})
logResultErrors(result)
content = result.code
}
// post process
if (transformer.postprocess) {
return transformer.postprocess(
content,
filePath,
config.config,
stylePart.attrs
)
}
return JSON.stringify(extractClassMap(content))
}