Skip to content

Commit 2309253

Browse files
yohodopoeddyerburgh
authored andcommitted
feat: add pre and post transform system (#146)
1 parent 34dd1e6 commit 2309253

18 files changed

+402
-135
lines changed

e2e/__projects__/babel-config/__snapshots__/test.js.snap

+6
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,9 @@ __options__.staticRenderFns = staticRenderFns
140140
141141
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkJhc2ljU3JjLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0E7QUFQQTtBQVNBO0FBQ0E7QUFDQTtBQUNBO0FBRkE7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSEE7QUFqQkEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdiYXNpYycsXG4gIGNvbXB1dGVkOiB7XG4gICAgaGVhZGluZ0NsYXNzZXM6IGZ1bmN0aW9uIGhlYWRpbmdDbGFzc2VzKCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcmVkOiB0aGlzLmlzQ3JhenksXG4gICAgICAgIGJsdWU6ICF0aGlzLmlzQ3JhenksXG4gICAgICAgIHNoYWRvdzogdGhpcy5pc0NyYXp5XG4gICAgICB9XG4gICAgfVxuICB9LFxuICBkYXRhOiBmdW5jdGlvbiBkYXRhKCkge1xuICAgIHJldHVybiB7XG4gICAgICBtc2c6ICdXZWxjb21lIHRvIFlvdXIgVnVlLmpzIEFwcCcsXG4gICAgICBpc0NyYXp5OiBmYWxzZVxuICAgIH1cbiAgfSxcbiAgbWV0aG9kczoge1xuICAgIHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiB0b2dnbGVDbGFzcygpIHtcbiAgICAgIHRoaXMuaXNDcmF6eSA9ICF0aGlzLmlzQ3JhenlcbiAgICB9XG4gIH1cbn1cbiJdfQ=="
142142
`;
143+
144+
exports[`processes PostCSS 1`] = `"<section><div></div> <div class=\\"red\\"></div></section>"`;
145+
146+
exports[`processes SCSS using user specified post transforms 1`] = `"<div class=\\"testA\\"><span class=\\"g\\"></span> <span class=\\"f\\"></span></div>"`;
147+
148+
exports[`processes SCSS using user specified pre transforms 1`] = `"<div class=\\"testA\\"><span class=\\"g\\"></span> <span class=\\"f\\"></span></div>"`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const { createTransformer } = require('babel-jest')
2+
module.exports = createTransformer({
3+
presets: ['@babel/preset-env'],
4+
plugins: ['transform-vue-jsx']
5+
})
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
<template>
2-
<div :class="$style.testPcss"></div>
2+
<section>
3+
<div :class="$style.testPcss"></div>
4+
<div :class="$style.red"></div>
5+
</section>
36
</template>
47

58
<style lang="postcss">
69
.testPcss {
7-
background-color: purple;
10+
background: color(purple a(90%));
811
}
912
</style>
1013

1114
<style module lang="pcss">
12-
/* This syntax is for postcss-custom-properties */
13-
--primary-color: green;
14-
15-
/* This syntax is for postcss-nesting, but invalid as Pure CSS */
16-
body {
17-
@media screen {
18-
background-color: grey;
19-
}
15+
.red {
16+
background: color(red a(90%));
2017
}
2118
</style>

e2e/__projects__/babel-config/components/Sass.vue

+5
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@
1313
.d
1414
background-color: blue
1515
</style>
16+
17+
<style lang="sass" module themed>
18+
.e
19+
background-color: blue
20+
</style>

e2e/__projects__/babel-config/components/Scss.vue

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<template>
2-
<div class="testA"></div>
2+
<div class="testA">
3+
<span :class="this.$style.g"></span>
4+
<span :class="this.$style.dark.f"></span>
5+
</div>
36
</template>
47

58
<style module lang="scss">
@@ -15,3 +18,9 @@
1518
background-color: red;
1619
}
1720
</style>
21+
22+
<style lang="scss" module themed>
23+
.f {
24+
background-color: red;
25+
}
26+
</style>

e2e/__projects__/babel-config/package.json

+7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
"babel-plugin-transform-vue-jsx": "^3.7.0",
2222
"jest": "^23.6.0",
2323
"node-sass": "^4.11.0",
24+
"postcss": "^7.0.13",
25+
"postcss-color-function": "^4.0.1",
2426
"vue-jest": "file:../../../"
2527
},
2628
"jest": {
@@ -40,6 +42,11 @@
4042
"vue-jest": {
4143
"pug": {
4244
"basedir": "./"
45+
},
46+
"transform": {
47+
"^scss$": "./scssTransform.js",
48+
"^pcss|postcss$": "./pcssTransform.js",
49+
"^js$": "./babel-transformer.js"
4350
}
4451
}
4552
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const postcss = require('postcss')
2+
var colorFunction = require('postcss-color-function')
3+
module.exports = {
4+
process: function(content, filepath, config, attrs) {
5+
return postcss([colorFunction()]).process(content).css
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const cssExtract = require('extract-from-css')
2+
module.exports = {
3+
postProcess: function postProcess(src, filepath, config, attrs) {
4+
const cssNames = cssExtract.extractClasses(src)
5+
const obj = {}
6+
for (let i = 0, l = cssNames.length; i < l; i++) {
7+
obj[cssNames[i]] = cssNames[i]
8+
}
9+
10+
if (attrs.themed) {
11+
return {
12+
light: obj,
13+
dark: obj
14+
}
15+
}
16+
return obj
17+
},
18+
preProcess: function postProcess(src, filepath, config, attrs) {
19+
return `${src}\n .g{width: 10px}`
20+
}
21+
}

e2e/__projects__/babel-config/test.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import Constructor from './components/Constructor.vue'
2525

2626
test('processes .vue files', () => {
2727
const wrapper = mount(Basic)
28+
expect(wrapper.vm.msg).toEqual('Welcome to Your Vue.js App')
2829
wrapper.vm.toggleClass()
2930
})
3031

@@ -119,7 +120,9 @@ it('processes Less', () => {
119120

120121
it('processes PostCSS', () => {
121122
const wrapper = mount(PostCss)
122-
expect(wrapper.is('div')).toBeTruthy()
123+
expect(wrapper.is('section')).toBeTruthy()
124+
expect(wrapper.vm.$style.red).toEqual('red')
125+
expect(wrapper.html()).toMatchSnapshot()
123126
})
124127

125128
test('processes pug templates', () => {
@@ -145,6 +148,7 @@ it('processes Sass', () => {
145148
expect(wrapper.vm.$style.a).toEqual('a')
146149
expect(wrapper.vm.$style.b).toEqual('b')
147150
expect(wrapper.vm.$style.c).toEqual('c')
151+
expect(wrapper.vm.$style.light).toBeUndefined()
148152
})
149153

150154
it('processes SCSS', () => {
@@ -154,6 +158,21 @@ it('processes SCSS', () => {
154158
expect(wrapper.vm.$style.c).toEqual('c')
155159
})
156160

161+
test('processes SCSS using user specified post transforms', () => {
162+
const wrapper = mount(Scss)
163+
expect(wrapper.vm.$style.light.a).toBeUndefined()
164+
expect(wrapper.vm.$style.light.f).toEqual('f')
165+
expect(wrapper.vm.$style.dark.f).toEqual('f')
166+
expect(wrapper.vm.$style.dark.g).toEqual('g')
167+
expect(wrapper.html()).toMatchSnapshot()
168+
})
169+
170+
test('processes SCSS using user specified pre transforms', () => {
171+
const wrapper = mount(Scss)
172+
expect(wrapper.vm.$style.g).toEqual('g')
173+
expect(wrapper.html()).toMatchSnapshot()
174+
})
175+
157176
test('process Stylus', () => {
158177
const wrapper = mount(Stylus)
159178
expect(wrapper.vm).toBeTruthy()

e2e/test-runner.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function runTest(dir) {
4343
run('npm install --silent')
4444

4545
log('Running tests')
46-
run('npm run test')
46+
run('npm run test')
4747

4848
success(`(${dir}) Complete`)
4949
}

lib/compilers/helpers/module-name-mapper-helper.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
const path = require('path')
2-
2+
const matchModuleImport = /^[^?]*~/
33
/**
4-
* Resolves the path to the file locally.
4+
* Resolves the path to the file/module.
55
*
66
* @param {String} to - the name of the file to resolve to
7-
* @param {String} localPath - the local path
7+
* @param {String} importPath - the local path
8+
* @param {String} fileType - extension of the file to be resolved
89
* @returns {String} path - path to the file to import
910
*/
10-
function localResolve(to, localPath) {
11-
if (localPath.startsWith('/')) {
12-
return localPath
11+
function resolve(to, importPath, fileType) {
12+
importPath =
13+
path.extname(importPath) === '' ? `${importPath}.${fileType}` : importPath
14+
if (importPath.startsWith('/')) {
15+
return importPath
16+
} else if (matchModuleImport.test(importPath)) {
17+
return require.resolve(importPath.replace(matchModuleImport, ''))
1318
}
14-
return path.join(path.dirname(to), localPath)
19+
return path.join(path.dirname(to), importPath)
1520
}
1621

1722
/**
@@ -20,12 +25,14 @@ function localResolve(to, localPath) {
2025
* @param {String} source - the original string
2126
* @param {String} filePath - the path of the current file (where the source originates)
2227
* @param {Object} jestConfig - the jestConfig holding the moduleNameMapper settings
28+
* @param {Object} fileType - extn of the file to be resolved
2329
* @returns {String} path - the final path to import (including replacements via moduleNameMapper)
2430
*/
2531
module.exports = function applyModuleNameMapper(
2632
source,
2733
filePath,
28-
jestConfig = {}
34+
jestConfig = {},
35+
fileType = ''
2936
) {
3037
if (!jestConfig.moduleNameMapper) return source
3138

@@ -47,5 +54,5 @@ module.exports = function applyModuleNameMapper(
4754
)
4855
}, source)
4956

50-
return localResolve(filePath, importPath)
57+
return resolve(filePath, importPath, fileType)
5158
}

lib/compilers/sass-compiler.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ module.exports = (content, filePath, jestConfig = {}) => {
2828
file: applyModuleNameMapper(
2929
url,
3030
prev === 'stdin' ? filePath : prev,
31-
jestConfig
31+
jestConfig,
32+
'sass'
3233
)
3334
})
3435
})

lib/compilers/scss-compiler.js

+3-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
const path = require('path')
2-
const fs = require('fs')
31
const ensureRequire = require('../ensure-require')
42
const getVueJestConfig = require('../utils').getVueJestConfig
53
const warn = require('../utils').warn
@@ -19,26 +17,17 @@ module.exports = (content, filePath, jestConfig = {}) => {
1917

2018
ensureRequire('scss', ['node-sass'])
2119
const sass = require('node-sass')
22-
23-
let scssResources = ''
24-
if (vueJestConfig.resources && vueJestConfig.resources.scss) {
25-
scssResources = vueJestConfig.resources.scss
26-
.map(scssResource => path.resolve(process.cwd(), scssResource))
27-
.filter(scssResourcePath => fs.existsSync(scssResourcePath))
28-
.map(scssResourcePath => fs.readFileSync(scssResourcePath).toString())
29-
.join('\n')
30-
}
31-
3220
try {
3321
return sass
3422
.renderSync({
35-
data: scssResources + content,
23+
data: content,
3624
outputStyle: 'compressed',
3725
importer: (url, prev, done) => ({
3826
file: applyModuleNameMapper(
3927
url,
4028
prev === 'stdin' ? filePath : prev,
41-
jestConfig
29+
jestConfig,
30+
'scss'
4231
)
4332
})
4433
})

lib/compilers/typescript-compiler.js

+12-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ const babelJest = require('babel-jest')
33
const getBabelOptions = require('../utils').getBabelOptions
44
const getTsJestConfig = require('../utils').getTsJestConfig
55
const stripInlineSourceMap = require('../utils').stripInlineSourceMap
6+
const getCustomTransformer = require('../utils').getCustomTransformer
7+
const getVueJestConfig = require('../utils').getVueJestConfig
68

79
module.exports = function compileTypescript(scriptContent, filePath, config) {
810
ensureRequire('typescript', ['typescript'])
911
const typescript = require('typescript')
10-
11-
const { tsconfig } = getTsJestConfig(config)
12+
const vueJestConfig = getVueJestConfig(config)
13+
const {
14+
tsconfig
15+
} = getTsJestConfig(config)
1216
const babelOptions = getBabelOptions(filePath)
1317

1418
const res = typescript.transpileModule(scriptContent, tsconfig)
@@ -26,10 +30,12 @@ module.exports = function compileTypescript(scriptContent, filePath, config) {
2630
plugins: [require('@babel/plugin-transform-modules-commonjs')]
2731
}
2832
}
29-
30-
const transformer = babelJest.createTransformer(
31-
Object.assign(inlineBabelOptions, { inputSourceMap })
33+
const customTransformer = getCustomTransformer(vueJestConfig['transform'], 'js');
34+
const transformer = customTransformer.process ? customTransformer : babelJest.createTransformer(
35+
Object.assign(inlineBabelOptions, {
36+
inputSourceMap
37+
})
3238
)
3339

3440
return transformer.process(res.outputText, filePath, config)
35-
}
41+
}

0 commit comments

Comments
 (0)