UNPKG

zoro-cli

Version:

https://github.com/vuejs/vue-cli

194 lines (174 loc) 5.74 kB
const fs = require('fs') const path = require('path') const { resolveCwd } = require('zoro-cli-util/resolve') /* eslint-disable-next-line no-unused-vars */ const findExisting = (context, files) => { /* eslint-disable no-restricted-syntax, no-await-in-loop */ for (const file of files) { if (fs.existsSync(path.join(context, file))) { return file } } return false /* eslint-enable no-restricted-syntax, no-await-in-loop */ } module.exports = ({ api, options, envUtil, args }) => { api.chainWebpack(webpackConfig => { const { target } = options const { modules: enableModules = false, extract = true, sourceMap = false, loaderOptions = {}, } = options.css || {} const isProd = envUtil.isProduction() // do no extract when build lib, will use standalone script to gen extracted css const shouldExtract = target !== 'lib' && ((isProd && extract !== false) || args.split) let hash = '' if (!isProd) { hash = '.[hash:8]' } else { hash = options.filenameHashing ? '.[contenthash:8]' : '' } const filename = `[name]${hash}.css` const extractOptions = { 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', // ]) // ) const hasPostCSSConfig = true function createCSSRule(lang, test, loader, _options) { const baseRule = webpackConfig.module .rule(lang) .test(test) // https://github.com/webpack-contrib/style-loader/issues/312#issuecomment-406444631 .sideEffects(true) function applyLoaders(rule, modules) { if (shouldExtract) { /* eslint-disable import/no-unresolved */ rule .use('extract-css-loader') .loader(require('mini-css-extract-plugin').loader) /* eslint-enable import/no-unresolved */ } else { const styleLoader = resolveCwd('vue') ? 'vue-style-loader' : 'style-loader' rule .use(styleLoader) .loader(styleLoader) .options({ sourceMap, ...loaderOptions.style, }) } const cssLoaderOptions = { root: api.resolve('.'), minimize: isProd, 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({ sourceMap, ...loaderOptions.postcss }) } if (loader) { rule .use(loader) .loader(loader) .options({ sourceMap, ..._options }) } } // 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, enableModules) } createCSSRule('css', /\.css$/) createCSSRule('postcss', /\.p(ost)?css$/) createCSSRule('scss', /\.scss$/, 'sass-loader', loaderOptions.sass) createCSSRule('sass', /\.sass$/, 'sass-loader', { indentedSyntax: true, ...loaderOptions.sass, }) createCSSRule('less', /\.less$/, 'less-loader', loaderOptions.less) createCSSRule('stylus', /\.styl(us)?$/, 'stylus-loader', { preferPathResolver: 'webpack', ...loaderOptions.stylus, }) // inject CSS extraction plugin if (shouldExtract) { /* eslint-disable import/no-unresolved */ webpackConfig .plugin('extract-css') .use(require('mini-css-extract-plugin'), [extractOptions]) /* eslint-enable import/no-unresolved */ } if (isProd) { // optimize CSS (dedupe) // cssnano 3 const cssProcessorOptions = { safe: true, autoprefixer: { disable: true }, mergeLonghand: false, } if (options.productionSourceMap && sourceMap) { cssProcessorOptions.map = { inline: false } } /* eslint-disable import/no-unresolved */ webpackConfig .plugin('optimize-css') .use(require('optimize-css-assets-webpack-plugin'), [ { canPrint: false, cssProcessorOptions, }, ]) /* eslint-enable import/no-unresolved */ } }) }