mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-04-21 11:58:36 -05:00
fix: css imports from js
BREAKING CHANGE: `css.modules` option has been removed. To import css files (or any other supported pre-processor files) as CSS Modules, append the request with a `?module` resourceQuery.
This commit is contained in:
+7
-3
@@ -13,11 +13,15 @@ Vue CLI uses PostCSS internally, and enables [autoprefixer](https://github.com/p
|
||||
|
||||
You can [use CSS Modules in `*.vue` files](https://vue-loader.vuejs.org/en/features/css-modules.html) out of the box with `<style module>`.
|
||||
|
||||
As for standalone style files, any files ending with `.module.(css|sass|scss|less|styl|stylus)` will be processed as CSS modules.
|
||||
If you wish to import style files as CSS Modules in JavaScript, you can import a file with a `?module` resourceQuery:
|
||||
|
||||
If you wish to be able to use CSS modules without the `.module` postfix, you can set `css: { modules: true }` in `vue.config.js`. This option does not affect `*.vue` files.
|
||||
``` js
|
||||
import styles from './foo.css?module'
|
||||
// works for all supported pre-processors as well
|
||||
import sassStyles from './foo.scss?module'
|
||||
```
|
||||
|
||||
If you wish to customize the CSS modules class name output you can set the `css: { localIdentName: [name]__[local]--[hash:base64:5]}` in `vue.config.js`.
|
||||
If you wish to customize the CSS modules class name output you can set the `css.localIdentName` option in `vue.config.js`.
|
||||
|
||||
### Pre-Processors
|
||||
|
||||
|
||||
@@ -22,20 +22,25 @@ const genConfig = (pkg = {}, env) => {
|
||||
return config
|
||||
}
|
||||
|
||||
const findRule = (config, lang) => config.module.rules.find(rule => {
|
||||
return rule.test.test(`.${lang}`)
|
||||
})
|
||||
const findRule = (config, lang, index = 1) => {
|
||||
const baseRule = config.module.rules.find(rule => {
|
||||
return rule.test.test(`.${lang}`)
|
||||
})
|
||||
// all CSS rules have oneOf with two child rules, one for <style lang="module">
|
||||
// and one for normal imports
|
||||
return baseRule.oneOf[index]
|
||||
}
|
||||
|
||||
const findLoaders = (config, lang) => {
|
||||
const rule = findRule(config, lang)
|
||||
const findLoaders = (config, lang, index) => {
|
||||
const rule = findRule(config, lang, index)
|
||||
if (!rule) {
|
||||
throw new Error(`rule not found for ${lang}`)
|
||||
}
|
||||
return rule.use.map(({ loader }) => loader.replace(/-loader$/, ''))
|
||||
}
|
||||
|
||||
const findOptions = (config, lang, _loader) => {
|
||||
const rule = findRule(config, lang)
|
||||
const findOptions = (config, lang, _loader, index) => {
|
||||
const rule = findRule(config, lang, index)
|
||||
const use = rule.use.find(({ loader }) => loader.includes(`${_loader}-loader`))
|
||||
return use.options || {}
|
||||
}
|
||||
@@ -70,16 +75,10 @@ test('production defaults', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('css.modules', () => {
|
||||
const config = genConfig({
|
||||
vue: {
|
||||
css: {
|
||||
modules: true
|
||||
}
|
||||
}
|
||||
})
|
||||
test('CSS Modules rules', () => {
|
||||
const config = genConfig()
|
||||
LANGS.forEach(lang => {
|
||||
expect(findOptions(config, lang, 'css')).toEqual({
|
||||
expect(findOptions(config, lang, 'css', 0)).toEqual({
|
||||
importLoaders: lang === 'css' ? 0 : 1, // no postcss-loader
|
||||
localIdentName: `[name]_[local]_[hash:base64:5]`,
|
||||
minimize: false,
|
||||
@@ -123,13 +122,12 @@ test('css.localIdentName', () => {
|
||||
const config = genConfig({
|
||||
vue: {
|
||||
css: {
|
||||
modules: true,
|
||||
localIdentName: localIdentName
|
||||
}
|
||||
}
|
||||
})
|
||||
LANGS.forEach(lang => {
|
||||
expect(findOptions(config, lang, 'css').localIdentName).toBe(localIdentName)
|
||||
expect(findOptions(config, lang, 'css', 0).localIdentName).toBe(localIdentName)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ module.exports = (api, options) => {
|
||||
api.chainWebpack(webpackConfig => {
|
||||
const {
|
||||
extract = true,
|
||||
modules = false,
|
||||
sourceMap = false,
|
||||
localIdentName = '[name]_[local]_[hash:base64:5]',
|
||||
loaderOptions = {}
|
||||
@@ -39,13 +38,15 @@ module.exports = (api, options) => {
|
||||
]))
|
||||
|
||||
function createCSSRule (lang, test, loader, options) {
|
||||
const normalRule = webpackConfig.module.rule(lang).test(test).resourceQuery(q => !/module/.test(q))
|
||||
applyLoaders(normalRule, modules)
|
||||
const baseRule = webpackConfig.module.rule(lang).test(test)
|
||||
|
||||
// rules for <style lang="module">
|
||||
const modulesRule = webpackConfig.module.rule(lang + '-modules').test(test).resourceQuery(/module/)
|
||||
const modulesRule = baseRule.oneOf('modules').resourceQuery(/module/)
|
||||
applyLoaders(modulesRule, true)
|
||||
|
||||
const normalRule = baseRule.oneOf('normal')
|
||||
applyLoaders(normalRule, false)
|
||||
|
||||
function applyLoaders (rule, modules) {
|
||||
if (shouldExtract) {
|
||||
rule
|
||||
|
||||
@@ -11,9 +11,8 @@ const schema = createSchema(joi => joi.object({
|
||||
|
||||
// css
|
||||
css: joi.object({
|
||||
modules: joi.boolean(),
|
||||
extract: joi.alternatives().try(joi.boolean(), joi.object()),
|
||||
localIdentName: joi.string(),
|
||||
extract: joi.alternatives().try(joi.boolean(), joi.object()),
|
||||
sourceMap: joi.boolean(),
|
||||
loaderOptions: joi.object({
|
||||
sass: joi.object(),
|
||||
@@ -63,7 +62,6 @@ exports.defaults = () => ({
|
||||
|
||||
css: {
|
||||
// extract: true,
|
||||
// modules: false,
|
||||
// localIdentName: '[name]_[local]_[hash:base64:5]',
|
||||
// sourceMap: false,
|
||||
// loaderOptions: {}
|
||||
|
||||
Reference in New Issue
Block a user