Skip to content

Commit c3b379d

Browse files
committed
feat: support rules with oneOf
1 parent 58239f6 commit c3b379d

File tree

5 files changed

+81
-10
lines changed

5 files changed

+81
-10
lines changed

Diff for: lib/plugin.js

+15-8
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,6 @@ module.exports = class VueLoaderPlugin {
9292
}
9393

9494
function cloneRule (rule, normalizedRule, vueUse) {
95-
if (rule.oneOf) {
96-
return Object.assign({}, rule, {
97-
oneOf: rule.oneOf.map((r, i) => cloneRule(r, normalizedRule.oneOf[i]))
98-
})
99-
}
100-
10195
// Assuming `test` and `resourceQuery` tests are executed in series and
10296
// synchronously (which is true based on RuleSet's implementation), we can
10397
// save the current resource being matched from `test` so that we can access
@@ -114,18 +108,31 @@ function cloneRule (rule, normalizedRule, vueUse) {
114108
if (parsed.lang == null) {
115109
return false
116110
}
117-
return normalizedRule.resource(`${currentResource}.${parsed.lang}`)
111+
const { resource, resourceQuery } = normalizedRule
112+
if (resource && !resource(`${currentResource}.${parsed.lang}`)) {
113+
return false
114+
}
115+
if (resourceQuery && !resourceQuery(query)) {
116+
return false
117+
}
118+
return true
118119
},
119120
use: [
120121
...(normalizedRule.use || []).map(cleanUse),
121-
...vueUse
122+
...rule.oneOf ? [] : vueUse
122123
]
123124
})
124125

125126
// delete shorthand since we have normalized use
126127
delete res.loader
127128
delete res.options
128129

130+
if (rule.oneOf) {
131+
res.oneOf = rule.oneOf.map((r, i) => {
132+
return cloneRule(r, normalizedRule.oneOf[i], vueUse)
133+
})
134+
}
135+
129136
return res
130137
}
131138

Diff for: lib/styleInjection.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ module.exports = function genStyleInjectionCode (
2323
// make sure to only pass id when necessary so that we don't inject
2424
// duplicate tags when multiple components import the same css file
2525
const scopedQuery = style.scoped ? `&scoped&id=${id}` : ``
26-
const query = `?vue&type=style&index=${i}${langQuery}${scopedQuery}`
26+
const moduleQuery = style.module ? `&cssModules` : ``
27+
const query = `?vue&type=style&index=${i}${langQuery}${scopedQuery}${moduleQuery}`
2728
return stringifyRequest(src + query)
2829
}
2930

Diff for: test/advanced.spec.js

+54
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,60 @@ test('extract CSS', done => {
105105
})
106106
})
107107

108+
test('support rules with oneOf', async () => {
109+
const run = (entry, assert) => new Promise((resolve, reject) => {
110+
mockBundleAndRun({
111+
entry,
112+
modify: config => {
113+
config.module.rules = [
114+
{ test: /\.vue$/, loader: 'vue-loader' },
115+
{
116+
test: /\.css$/,
117+
use: 'vue-style-loader',
118+
oneOf: [
119+
{
120+
resourceQuery: /cssModules/,
121+
use: [
122+
{
123+
loader: 'css-loader',
124+
options: {
125+
modules: true,
126+
localIdentName: '[local]_[hash:base64:5]'
127+
}
128+
}
129+
]
130+
},
131+
{
132+
use: ['css-loader']
133+
}
134+
]
135+
}
136+
]
137+
}
138+
}, res => {
139+
const { jsdomError, bundleError } = res
140+
if (jsdomError) return reject(jsdomError)
141+
if (bundleError) return reject(bundleError)
142+
assert(res)
143+
resolve()
144+
})
145+
})
146+
147+
await run('basic.vue', ({ window }) => {
148+
let style = window.document.querySelector('style').textContent
149+
style = normalizeNewline(style)
150+
expect(style).toContain('comp-a h2 {\n color: #f00;\n}')
151+
})
152+
153+
await run('css-modules-simple.vue', ({ window, instance }) => {
154+
const className = instance.$style.red
155+
expect(className).toMatch(/^red_\w{5}/)
156+
let style = window.document.querySelector('style').textContent
157+
style = normalizeNewline(style)
158+
expect(style).toContain('.' + className + ' {\n color: red;\n}')
159+
})
160+
})
161+
108162
// TODO
109163
// test('multiple rule definitions', done => {
110164
// mockBundleAndRun({

Diff for: test/fixtures/css-modules-simple.vue

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<style module>
2+
.red {
3+
color: red;
4+
}
5+
</style>
6+
7+
<script>
8+
export default {}
9+
</script>

Diff for: test/style.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ test('postcss', done => {
106106
})
107107
})
108108

109-
test('css-modules', async () => {
109+
test('CSS Modules', async () => {
110110
function testWithIdent (localIdentName, regexToMatch) {
111111
return new Promise((resolve, reject) => {
112112
const baseLoaders = [

0 commit comments

Comments
 (0)