-
Notifications
You must be signed in to change notification settings - Fork 159
/
process-style.js
136 lines (121 loc) · 3.26 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
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 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 => {
const absolutePath = path.resolve(process.cwd(), resource)
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-${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))
}