Skip to content

Commit

Permalink
fix: css imports from js
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
yyx990803 committed May 10, 2018
1 parent 76196ba commit 1b5bdde
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 28 deletions.
10 changes: 7 additions & 3 deletions docs/css.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
34 changes: 16 additions & 18 deletions packages/@vue/cli-service/__tests__/css.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 || {}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
})
})

Expand Down
9 changes: 5 additions & 4 deletions packages/@vue/cli-service/lib/config/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand All @@ -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
Expand Down
4 changes: 1 addition & 3 deletions packages/@vue/cli-service/lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -63,7 +62,6 @@ exports.defaults = () => ({

css: {
// extract: true,
// modules: false,
// localIdentName: '[name]_[local]_[hash:base64:5]',
// sourceMap: false,
// loaderOptions: {}
Expand Down

0 comments on commit 1b5bdde

Please sign in to comment.