Skip to content

Commit 4c74e43

Browse files
jeremyzahnereddyerburgh
authored andcommitted
feat: add style injection for modules in functional components (#92)
1 parent e694fc7 commit 4c74e43

File tree

5 files changed

+111
-7
lines changed

5 files changed

+111
-7
lines changed

lib/process.js

+20-5
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,26 @@ module.exports = function (src, filePath, jestConfig) {
104104
.join('')
105105

106106
if (styleStr.length !== 0) {
107-
output += '\n;(function() {' +
108-
'\nvar beforeCreate = __vue__options__.beforeCreate' +
109-
'\nvar styleFn = function () { ' + styleStr + ' }' +
110-
'\n__vue__options__.beforeCreate = beforeCreate ? [].concat(beforeCreate, styleFn) : [styleFn]' +
111-
'\n})()'
107+
if (parts.template.attrs.functional) {
108+
output += `
109+
;(function() {
110+
var originalRender = __vue__options__.render
111+
var styleFn = function () { ${styleStr} }
112+
__vue__options__.render = function renderWithStyleInjection (h, context) {
113+
styleFn.call(context)
114+
return originalRender(h, context)
115+
}
116+
})()
117+
`
118+
} else {
119+
output += `
120+
;(function() {
121+
var beforeCreate = __vue__options__.beforeCreate
122+
var styleFn = function () { ${styleStr} }
123+
__vue__options__.beforeCreate = beforeCreate ? [].concat(beforeCreate, styleFn) : [styleFn]
124+
})()
125+
`
126+
}
112127
}
113128
}
114129

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<template functional>
2+
<div>
3+
<div :class="$style.testAFunctional"></div>
4+
<div :class="[ $style.testAFunctional ]"></div>
5+
<div :class="{[$style.testBFunctional]: true }"></div>
6+
<div :class="[$style.testAFunctional, { [$style.testBFunctional]: true }]"></div>
7+
<div :class="[$otherStyle.otherTestAFunctional, { [$otherStyle.otherTestBFunctional]: true }]"></div>
8+
</div>
9+
</template>
10+
11+
<style module lang="sass">
12+
.testAFunctional
13+
background-color: red
14+
.testBFunctional
15+
background-color: blue
16+
</style>
17+
18+
<style module="$otherStyle" lang="scss">
19+
.otherTestAFunctional {
20+
background-color: red;
21+
}
22+
.otherTestBFunctional {
23+
background-color: blue;
24+
}
25+
</style>
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<script>
2+
export default {
3+
name: 'ScssModuleFunctional',
4+
functional: true,
5+
}
6+
</script>
7+
8+
<template functional>
9+
<div>
10+
<div :class="$style.testAFunctional"></div>
11+
<div :class="[ $style.testAFunctional ]"></div>
12+
<div :class="{[$style.testBFunctional]: true }"></div>
13+
<div :class="[$style.testAFunctional, { [$style.testBFunctional]: true }]"></div>
14+
<div :class="[$otherStyle.otherTestAFunctional, { [$otherStyle.otherTestBFunctional]: true }]"></div>
15+
</div>
16+
</template>
17+
18+
<style module lang="scss">
19+
.testAFunctional {
20+
background-color: red;
21+
}
22+
.testBFunctional {
23+
background-color: blue;
24+
}
25+
</style>
26+
27+
<style module="$otherStyle" lang="scss">
28+
.otherTestAFunctional {
29+
background-color: red;
30+
}
31+
.otherTestBFunctional {
32+
background-color: blue;
33+
}
34+
</style>

test/sass.spec.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { shallow } from 'vue-test-utils'
1+
import { shallow, mount } from 'vue-test-utils'
22
import Sass from './resources/Sass.vue'
33
import SassModule from './resources/SassModule.vue'
4+
import SassModuleFunctional from './resources/SassModuleFunctional.vue'
45

56
describe('processes .vue file with sass style', () => {
67
it('does not error on sass', () => {
@@ -9,13 +10,20 @@ describe('processes .vue file with sass style', () => {
910
it('does not error on sass module', () => {
1011
expect(() => shallow(SassModule)).not.toThrow()
1112
})
13+
it('does not error on sass module when functional', () => {
14+
expect(() => mount(SassModuleFunctional)).not.toThrow()
15+
})
1216
})
1317

1418
describe('processes .vue files which combine sass and modules', () => {
1519
let wrapper
20+
let functionalWrapper
21+
1622
beforeEach(() => {
1723
wrapper = shallow(SassModule)
24+
functionalWrapper = mount(SassModuleFunctional)
1825
})
26+
1927
it('does inject classes to $style', () => {
2028
expect(wrapper.vm.$style).toBeDefined()
2129
expect(wrapper.vm.$style.testA).toBeDefined()
@@ -24,6 +32,13 @@ describe('processes .vue files which combine sass and modules', () => {
2432
expect(wrapper.vm.$style.testB).toEqual('testB')
2533
})
2634

35+
it('does inject classes to $style for functional components', () => {
36+
expect(functionalWrapper.findAll('.testAFunctional')).toHaveLength(3)
37+
expect(functionalWrapper.findAll('.testBFunctional')).toHaveLength(2)
38+
expect(functionalWrapper.findAll('.otherTestAFunctional')).toHaveLength(1)
39+
expect(functionalWrapper.findAll('.otherTestBFunctional')).toHaveLength(1)
40+
})
41+
2742
describe('entrypoint: direct import in SFC', () => {
2843
let wrapper
2944
beforeEach(() => {

test/scss.spec.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { shallow } from 'vue-test-utils'
1+
import { shallow, mount } from 'vue-test-utils'
22
import Scss from './resources/Scss.vue'
33
import ScssModule from './resources/ScssModule.vue'
4+
import ScssModuleFunctional from './resources/ScssModuleFunctional.vue'
45

56
describe('processes .vue file with scss style', () => {
67
it('does not error on scss', () => {
@@ -9,13 +10,20 @@ describe('processes .vue file with scss style', () => {
910
it('does not error on scss module', () => {
1011
expect(() => shallow(ScssModule)).not.toThrow()
1112
})
13+
it('does not error on scss module when functional', () => {
14+
expect(() => mount(ScssModuleFunctional)).not.toThrow()
15+
})
1216
})
1317

1418
describe('processes .vue files which combine scss and modules', () => {
1519
let wrapper
20+
let functionalWrapper
21+
1622
beforeEach(() => {
1723
wrapper = shallow(ScssModule)
24+
functionalWrapper = mount(ScssModuleFunctional)
1825
})
26+
1927
it('does inject classes to $style', () => {
2028
expect(wrapper.vm.$style).toBeDefined()
2129
expect(wrapper.vm.$style.testA).toBeDefined()
@@ -24,6 +32,13 @@ describe('processes .vue files which combine scss and modules', () => {
2432
expect(wrapper.vm.$style.testB).toEqual('testB')
2533
})
2634

35+
it('does inject classes to $style for functional components', () => {
36+
expect(functionalWrapper.findAll('.testAFunctional')).toHaveLength(3)
37+
expect(functionalWrapper.findAll('.testBFunctional')).toHaveLength(2)
38+
expect(functionalWrapper.findAll('.otherTestAFunctional')).toHaveLength(1)
39+
expect(functionalWrapper.findAll('.otherTestBFunctional')).toHaveLength(1)
40+
})
41+
2742
describe('entrypoint: direct import in SFC', () => {
2843
let wrapper
2944
beforeEach(() => {

0 commit comments

Comments
 (0)