Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 98c07b1

Browse filesBrowse files
committed
feat(cssModules ): namedExport support
For v17 Support css-loader : `options.modules.namedexport` https://github.com/webpack-contrib/css-loader/tree/v4.3.0#namedexport https://github.com/webpack-contrib/css-loader#namedexport
1 parent d67c85c commit 98c07b1
Copy full SHA for 98c07b1

File tree

4 files changed

+100
-8
lines changed
Filter options

4 files changed

+100
-8
lines changed

‎src/cssModules.ts

Copy file name to clipboardExpand all lines: src/cssModules.ts
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@ export function genCSSModulesCode(
66
needsHotReload: boolean
77
): string {
88
const styleVar = `style${index}`
9-
let code = `\nimport ${styleVar} from ${request}`
9+
let code = `\nimport * as ${styleVar} from ${request}`
1010

1111
// inject variable
1212
const name = typeof moduleName === 'string' ? moduleName : '$style'
13-
code += `\ncssModules["${name}"] = ${styleVar}`
13+
14+
// omit no default export error
15+
code += `\ncssModules["${name}"] = {...${styleVar}}.default || ${styleVar}`
1416

1517
if (needsHotReload) {
1618
code += `
1719
if (module.hot) {
1820
module.hot.accept(${request}, () => {
19-
cssModules["${name}"] = ${styleVar}
21+
cssModules["${name}"] = {...${styleVar}}.default || ${styleVar}
2022
__VUE_HMR_RUNTIME__.rerender("${id}")
2123
})
2224
}`

‎src/pitcher.ts

Copy file name to clipboardExpand all lines: src/pitcher.ts
+11-4Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,16 @@ export const pitch = function () {
105105
? [styleInlineLoaderPath]
106106
: loaders.slice(0, cssLoaderIndex + 1)
107107
const beforeLoaders = loaders.slice(cssLoaderIndex + 1)
108+
109+
const { namedExport = false } = // @ts-ignore
110+
loaders[cssLoaderIndex]?.options?.modules || {}
111+
108112
return genProxyModule(
109113
[...afterLoaders, stylePostLoaderPath, ...beforeLoaders],
110114
context,
111115
!!query.module || query.inline != null,
112-
(query.lang as string) || 'css'
116+
(query.lang as string) || 'css',
117+
namedExport
113118
)
114119
}
115120
}
@@ -134,15 +139,17 @@ function genProxyModule(
134139
loaders: (Loader | string)[],
135140
context: LoaderContext<VueLoaderOptions>,
136141
exportDefault = true,
137-
lang = 'js'
142+
lang = 'js',
143+
cssNamedExport = false
138144
) {
139145
const request = genRequest(loaders, lang, context)
140146
// return a proxy module which simply re-exports everything from the
141147
// actual request. Note for template blocks the compiled module has no
142148
// default export.
143149
return (
144-
(exportDefault ? `export { default } from ${request}; ` : ``) +
145-
`export * from ${request}`
150+
(exportDefault && !cssNamedExport
151+
? `export { default } from ${request}; `
152+
: ``) + `export * from ${request}`
146153
)
147154
}
148155

‎src/pluginWebpack5.ts

Copy file name to clipboardExpand all lines: src/pluginWebpack5.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ class VueLoaderPlugin {
154154
// get vue-loader options
155155
const vueLoaderUseIndex = vueUse.findIndex((u) => {
156156
// FIXME: this code logic is incorrect when project paths starts with `vue-loader-something`
157-
return /^vue-loader|(\/|\\|@)vue-loader/.test(u.loader)
157+
return /^vue-loader|^@\S+\/vue-loader/.test(u.loader)
158158
})
159159

160160
if (vueLoaderUseIndex < 0) {

‎test/style.spec.ts

Copy file name to clipboardExpand all lines: test/style.spec.ts
+83Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,89 @@ test('CSS Modules', async () => {
166166
)
167167
})
168168

169+
test('CSS Modules namedExport', async () => {
170+
const testWithIdent = async (
171+
localIdentName: string | undefined,
172+
regexToMatch: RegExp
173+
) => {
174+
const baseLoaders = [
175+
{
176+
loader: 'style-loader',
177+
options: {
178+
modules: {
179+
namedExport: true,
180+
},
181+
},
182+
},
183+
{
184+
loader: 'css-loader',
185+
options: {
186+
modules: {
187+
localIdentName,
188+
namedExport: true,
189+
},
190+
},
191+
},
192+
]
193+
194+
const { window, instance } = await mockBundleAndRun({
195+
entry: 'css-modules.vue',
196+
modify: (config: any) => {
197+
config!.module!.rules = [
198+
{
199+
test: /\.vue$/,
200+
loader: 'vue-loader',
201+
},
202+
{
203+
test: /\.css$/,
204+
use: baseLoaders,
205+
},
206+
{
207+
test: /\.stylus$/,
208+
use: [...baseLoaders, 'stylus-loader'],
209+
},
210+
]
211+
},
212+
})
213+
214+
// get local class name
215+
const className = instance.$style.red
216+
expect(className).toMatch(regexToMatch)
217+
218+
// class name in style
219+
let style = [].slice
220+
.call(window.document.querySelectorAll('style'))
221+
.map((style: any) => {
222+
return style!.textContent
223+
})
224+
.join('\n')
225+
style = normalizeNewline(style)
226+
expect(style).toContain('.' + className + ' {\n color: red;\n}')
227+
228+
// animation name
229+
const match = style.match(/@keyframes\s+(\S+)\s+{/)
230+
expect(match).toHaveLength(2)
231+
const animationName = match[1]
232+
expect(animationName).not.toBe('fade')
233+
expect(style).toContain('animation: ' + animationName + ' 1s;')
234+
235+
// default module + pre-processor + scoped
236+
const anotherClassName = instance.$style.red
237+
expect(anotherClassName).toMatch(regexToMatch)
238+
const id = 'data-v-' + genId('css-modules.vue')
239+
expect(style).toContain('.' + anotherClassName + '[' + id + ']')
240+
}
241+
242+
// default ident
243+
await testWithIdent(undefined, /^\w{21,}/)
244+
245+
// custom ident
246+
await testWithIdent(
247+
'[path][name]---[local]---[hash:base64:5]',
248+
/css-modules---red---\w{5}/
249+
)
250+
})
251+
169252
test('CSS Modules Extend', async () => {
170253
const baseLoaders = [
171254
'style-loader',

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.