Skip to content

feat!: deprecate css.modules in favor of css.requireModuleExtension #4387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions docs/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,20 @@ See [the plugin's README](https://github.com/vuejs/vue-cli/blob/dev/packages/%40

### css.modules

Deprecated since v4, please use [`css.requireModuleExtension`](#css-requireModuleExtension) instead.

In v3 this means the opposite of `css.requireModuleExtension`.

### css.requireModuleExtension

- Type: `boolean`
- Default: `false`
- Default: `true`

By default, only files that ends in `*.module.[ext]` are treated as CSS modules. Setting this to `false` will allow you to drop `.module` in the filenames and treat all `*.(css|scss|sass|less|styl(us)?)` files as CSS modules.

By default, only files that ends in `*.module.[ext]` are treated as CSS modules. Setting this to `true` will allow you to drop `.module` in the filenames and treat all `*.(css|scss|sass|less|styl(us)?)` files as CSS modules.
::: tip
If you have customized CSS Modules configurations in `css.loaderOptions.css`, then the `css.requireModuleExtension` field must be explictly configured to `true` or `false`, otherwise we can't be sure whether you want to apply these options to all CSS files or not.
:::

See also: [Working with CSS > CSS Modules](../guide/css.md#css-modules)

Expand Down
4 changes: 2 additions & 2 deletions docs/guide/css.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ import styles from './foo.module.css'
import sassStyles from './foo.module.scss'
```

If you want to drop the `.module` in the filenames, set `css.modules` to `true` in `vue.config.js`:
If you want to drop the `.module` in the filenames, set `css.requireModuleExtension` to `false` in `vue.config.js`:

``` js
// vue.config.js
module.exports = {
css: {
modules: true
requireModuleExtension: false
}
}
```
Expand Down
13 changes: 11 additions & 2 deletions docs/zh/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,19 @@ module.exports = {

### css.modules

从 v4 起已弃用,请使用[`css.requireModuleExtension`](#css-requireModuleExtension)。
在 v3 中,这个选项含义与 `css.requireModuleExtension` 相反。

### css.requireModuleExtension

- Type: `boolean`
- Default: `false`
- Default: `true`

默认情况下,只有 `*.module.[ext]` 结尾的文件才会被视作 CSS Modules 模块。设置为 `true` 后你就可以去掉文件名中的 `.module` 并将所有的 `*.(css|scss|sass|less|styl(us)?)` 文件视为 CSS Modules 模块。
默认情况下,只有 `*.module.[ext]` 结尾的文件才会被视作 CSS Modules 模块。设置为 `false` 后你就可以去掉文件名中的 `.module` 并将所有的 `*.(css|scss|sass|less|styl(us)?)` 文件视为 CSS Modules 模块。

::: tip 提示
如果你在 `css.loaderOptions.css` 里配置了自定义的 CSS Module 选项,则 `css.requireModuleExtension` 必须被显式地指定为 `true` 或者 `false`,否则我们无法确定你是否希望将这些自定义配置应用到所有 CSS 文件中。
:::

更多细节可查阅:[配合 CSS > CSS Modules](../guide/css.md#css-modules)

Expand Down
4 changes: 2 additions & 2 deletions docs/zh/guide/css.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,13 @@ import styles from './foo.module.css'
import sassStyles from './foo.module.scss'
```

如果你想去掉文件名中的 `.module`,可以设置 `vue.config.js` 中的 `css.modules` 为 `true`:
如果你想去掉文件名中的 `.module`,可以设置 `vue.config.js` 中的 `css.requireModuleExtension` 为 `false`:

``` js
// vue.config.js
module.exports = {
css: {
modules: true
requireModuleExtension: false
}
}
```
Expand Down
117 changes: 116 additions & 1 deletion packages/@vue/cli-service/__tests__/css.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
const { logs } = require('@vue/cli-shared-utils')
const Service = require('../lib/Service')

beforeEach(() => {
logs.warn = []
})

const LANGS = ['css', 'sass', 'scss', 'less', 'styl', 'stylus']
const extractLoaderPath = require('mini-css-extract-plugin').loader

Expand Down Expand Up @@ -82,7 +87,7 @@ test('CSS Modules rules', () => {
const config = genConfig({
vue: {
css: {
modules: true
requireModuleExtension: false
}
}
})
Expand All @@ -103,6 +108,116 @@ test('CSS Modules rules', () => {
})
})

test('Customized CSS Modules rules', () => {
const userOptions = {
vue: {
css: {
loaderOptions: {
css: {
modules: {
localIdentName: '[folder]-[name]-[local][emoji]'
}
}
}
}
}
}

expect(() => {
genConfig(userOptions)
}).toThrow('`css.requireModuleExtension` is required when custom css modules options provided')

userOptions.vue.css.requireModuleExtension = true
const config = genConfig(userOptions)

LANGS.forEach(lang => {
const expected = {
importLoaders: 1, // no postcss-loader
sourceMap: false,
modules: {
localIdentName: `[folder]-[name]-[local][emoji]`
}
}
// vue-modules rules
expect(findOptions(config, lang, 'css', 0)).toEqual(expected)
// normal-modules rules
expect(findOptions(config, lang, 'css', 2)).toEqual(expected)
// normal rules
expect(findOptions(config, lang, 'css', 3)).not.toEqual(expected)
})
})

test('deprecate `css.modules` option', () => {
const config = genConfig({
vue: {
css: {
modules: true,
loaderOptions: {
css: {
modules: {
localIdentName: '[folder]-[name]-[local][emoji]'
}
}
}
}
}
})
expect(logs.warn.some(([msg]) => msg.match('please use "css.requireModuleExtension" instead'))).toBe(true)

LANGS.forEach(lang => {
const expected = {
importLoaders: 1, // no postcss-loader
sourceMap: false,
modules: {
localIdentName: `[folder]-[name]-[local][emoji]`
}
}
// vue-modules rules
expect(findOptions(config, lang, 'css', 0)).toEqual(expected)
// normal-modules rules
expect(findOptions(config, lang, 'css', 2)).toEqual(expected)
// normal rules
expect(findOptions(config, lang, 'css', 3)).toEqual(expected)
})
})

test('favor `css.requireModuleExtension` over `css.modules`', () => {
const config = genConfig({
vue: {
css: {
requireModuleExtension: false,
modules: false,

loaderOptions: {
css: {
modules: {
localIdentName: '[folder]-[name]-[local][emoji]'
}
}
}
}
}
})

expect(logs.warn.some(([msg]) => msg.match('"css.modules" will be ignored in favor of "css.requireModuleExtension"'))).toBe(true)

LANGS.forEach(lang => {
const expected = {
importLoaders: 1, // no postcss-loader
sourceMap: false,
modules: {
localIdentName: `[folder]-[name]-[local][emoji]`
}
}
// vue-modules rules
expect(findOptions(config, lang, 'css', 0)).toEqual(expected)
// normal-modules rules
expect(findOptions(config, lang, 'css', 2)).toEqual(expected)
// normal rules
expect(findOptions(config, lang, 'css', 3)).toEqual(expected)
})
})

test('css.extract', () => {
const config = genConfig({
vue: {
Expand Down
16 changes: 16 additions & 0 deletions packages/@vue/cli-service/lib/Service.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,22 @@ module.exports = class Service {
resolvedFrom = 'inline options'
}


if (resolved.css && typeof resolved.css.modules !== 'undefined') {
if (typeof resolved.css.requireModuleExtension !== 'undefined') {
warn(
`You have set both "css.modules" and "css.requireModuleExtension" in ${chalk.bold('vue.config.js')}, ` +
`"css.modules" will be ignored in favor of "css.requireModuleExtension".`
)
} else {
warn(
`"css.modules" option in ${chalk.bold('vue.config.js')} ` +
`is deprecated now, please use "css.requireModuleExtension" instead.`
)
resolved.css.requireModuleExtension = !resolved.css.modules
}
}

// normalize some options
ensureSlash(resolved, 'publicPath')
if (typeof resolved.publicPath === 'string') {
Expand Down
13 changes: 11 additions & 2 deletions packages/@vue/cli-service/lib/config/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ module.exports = (api, rootOptions) => {
loaderOptions = {}
} = rootOptions.css || {}

let { requireModuleExtension } = rootOptions.css || {}
if (typeof requireModuleExtension === 'undefined') {
if (loaderOptions.css && loaderOptions.css.modules) {
throw new Error('`css.requireModuleExtension` is required when custom css modules options provided')
}
requireModuleExtension = true
}

const shouldExtract = extract !== false && !shadowMode
const filename = getAssetPath(
rootOptions,
Expand Down Expand Up @@ -91,8 +99,7 @@ module.exports = (api, rootOptions) => {

// rules for normal CSS imports
const normalRule = baseRule.oneOf('normal')
const treatAllAsModules = !!(rootOptions.css && rootOptions.css.modules)
applyLoaders(normalRule, treatAllAsModules)
applyLoaders(normalRule, !requireModuleExtension)

function applyLoaders (rule, isCssModule) {
if (shouldExtract) {
Expand Down Expand Up @@ -127,6 +134,8 @@ module.exports = (api, rootOptions) => {
localIdentName: '[name]_[local]_[hash:base64:5]',
...cssLoaderOptions.modules
}
} else {
delete cssLoaderOptions.modules
}

rule
Expand Down
2 changes: 2 additions & 0 deletions packages/@vue/cli-service/lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ const schema = createSchema(joi => joi.object({

// css
css: joi.object({
// TODO: deprecate this after joi 16 release
modules: joi.boolean(),
requireModuleExtension: joi.boolean(),
extract: joi.alternatives().try(joi.boolean(), joi.object()),
sourceMap: joi.boolean(),
loaderOptions: joi.object({
Expand Down