Files
vue-cli/packages/@vue/cli-service/lib/config/css.js
Guillaume Chau 96778b2caf chore: update main deps (#1772)
* chore: update main deps

* chore: update ts types

* chore: update generator deps versions

* fix: ts-jest

* chore: upgrade ts-jest again

* fix: re-generated yarn.lock

* chore: more upgrades

* fix: jest test matching on Windows
2018-07-08 13:56:10 +02:00

158 lines
4.6 KiB
JavaScript

const fs = require('fs')
const path = require('path')
const findExisting = (context, files) => {
for (const file of files) {
if (fs.existsSync(path.join(context, file))) {
return file
}
}
}
module.exports = (api, options) => {
api.chainWebpack(webpackConfig => {
const getAssetPath = require('../util/getAssetPath')
const {
modules = false,
extract = true,
sourceMap = false,
loaderOptions = {}
} = options.css || {}
const shadowMode = !!process.env.VUE_CLI_CSS_SHADOW_MODE
const isProd = process.env.NODE_ENV === 'production'
const shouldExtract = isProd && extract !== false && !shadowMode
const filename = getAssetPath(
options,
`css/[name].[contenthash:8].css`,
true /* placeAtRootIfRelative */
)
const extractOptions = Object.assign({
filename,
chunkFilename: filename
}, extract && typeof extract === 'object' ? extract : {})
// check if the project has a valid postcss config
// if it doesn't, don't use postcss-loader for direct style imports
// because otherwise it would throw error when attempting to load postcss config
const hasPostCSSConfig = !!(api.service.pkg.postcss || findExisting(api.resolve('.'), [
'.postcssrc',
'.postcssrc.js',
'postcss.config.js',
'.postcssrc.yaml',
'.postcssrc.json'
]))
function createCSSRule (lang, test, loader, options) {
const baseRule = webpackConfig.module.rule(lang).test(test)
// rules for <style lang="module">
const vueModulesRule = baseRule.oneOf('vue-modules').resourceQuery(/module/)
applyLoaders(vueModulesRule, true)
// rules for <style>
const vueNormalRule = baseRule.oneOf('vue').resourceQuery(/\?vue/)
applyLoaders(vueNormalRule, false)
// rules for *.module.* files
const extModulesRule = baseRule.oneOf('normal-modules').test(/\.module\.\w+$/)
applyLoaders(extModulesRule, true)
// rules for normal CSS imports
const normalRule = baseRule.oneOf('normal')
applyLoaders(normalRule, modules)
function applyLoaders (rule, modules) {
if (shouldExtract) {
rule
.use('extract-css-loader')
.loader(require('mini-css-extract-plugin').loader)
} else {
rule
.use('vue-style-loader')
.loader('vue-style-loader')
.options({
sourceMap,
shadowMode
})
}
const cssLoaderOptions = Object.assign({
sourceMap,
importLoaders: (
1 + // stylePostLoader injected by vue-loader
hasPostCSSConfig +
!!loader
)
}, loaderOptions.css)
if (modules) {
const {
localIdentName = '[name]_[local]_[hash:base64:5]'
} = loaderOptions.css || {}
Object.assign(cssLoaderOptions, {
modules,
localIdentName
})
}
rule
.use('css-loader')
.loader('css-loader')
.options(cssLoaderOptions)
if (hasPostCSSConfig) {
rule
.use('postcss-loader')
.loader('postcss-loader')
.options(Object.assign({ sourceMap }, loaderOptions.postcss))
}
if (loader) {
rule
.use(loader)
.loader(loader)
.options(Object.assign({ sourceMap }, options))
}
}
}
createCSSRule('css', /\.css$/)
createCSSRule('postcss', /\.p(ost)?css$/)
createCSSRule('scss', /\.scss$/, 'sass-loader', loaderOptions.sass)
createCSSRule('sass', /\.sass$/, 'sass-loader', Object.assign({
indentedSyntax: true
}, loaderOptions.sass))
createCSSRule('less', /\.less$/, 'less-loader', loaderOptions.less)
createCSSRule('stylus', /\.styl(us)?$/, 'stylus-loader', Object.assign({
preferPathResolver: 'webpack'
}, loaderOptions.stylus))
// inject CSS extraction plugin
if (shouldExtract) {
webpackConfig
.plugin('extract-css')
.use(require('mini-css-extract-plugin'), [extractOptions])
}
if (isProd) {
// optimize CSS (dedupe)
const cssProcessorOptions = {
safe: true,
autoprefixer: { disable: true },
mergeLonghand: false
}
if (options.productionSourceMap && sourceMap) {
cssProcessorOptions.map = { inline: false }
}
webpackConfig
.plugin('optimize-css')
.use(require('@intervolga/optimize-cssnano-plugin'), [{
sourceMap: options.productionSourceMap && sourceMap,
cssnanoOptions: cssProcessorOptions
}])
}
})
}