From 1142339cce58f10dc5f71aa8b18fce3d1770e635 Mon Sep 17 00:00:00 2001 From: Evan You Date: Fri, 26 Jan 2018 12:18:17 -0500 Subject: [PATCH] fix: skip postcss-loader if no postcss config is present --- .../lib/createConfigPlugin.js | 8 +++++- .../@vue/cli-service/__tests__/css.spec.js | 13 ++++++++-- packages/@vue/cli-service/lib/config/css.js | 26 ++++++++++++++++++- .../lib/webpack/CSSLoaderResolver.js | 4 ++- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/packages/@vue/cli-service-global/lib/createConfigPlugin.js b/packages/@vue/cli-service-global/lib/createConfigPlugin.js index 4d15802111..9f1ada4289 100644 --- a/packages/@vue/cli-service-global/lib/createConfigPlugin.js +++ b/packages/@vue/cli-service-global/lib/createConfigPlugin.js @@ -21,6 +21,8 @@ module.exports = function createConfigPlugin (context, entry) { } // ensure loaders can be resolved properly + // this is done by locating vue's install location (which is a + // dependency of the global service) const modulePath = path.resolve(require.resolve('vue'), '../../../') config.resolveLoader .modules @@ -74,7 +76,9 @@ module.exports = function createConfigPlugin (context, entry) { .use('babel-loader') .tap(() => babelOptions) - // set inline eslint options + // check eslint config presence + // otherwise eslint-loader goes all the way up to look for eslintrc, can be + // messed up when the project is inside another project. const ESLintConfigFile = findExisting(context, [ '.eslintrc.js', '.eslintrc.yaml', @@ -86,6 +90,8 @@ module.exports = function createConfigPlugin (context, entry) { const hasESLintConfig = ESLintConfigFile === 'package.json' ? !!(require(path.join(context, 'package.json')).eslintConfig) : !!ESLintConfigFile + + // set inline eslint options config.module .rule('eslint') .include diff --git a/packages/@vue/cli-service/__tests__/css.spec.js b/packages/@vue/cli-service/__tests__/css.spec.js index 874e65901c..37ac222510 100644 --- a/packages/@vue/cli-service/__tests__/css.spec.js +++ b/packages/@vue/cli-service/__tests__/css.spec.js @@ -59,7 +59,7 @@ const expectedCssLoaderModulesOptions = { } test('default loaders', () => { - const config = genConfig() + const config = genConfig({ postcss: {}}) LANGS.forEach(lang => { const loader = lang === 'css' ? [] : LOADERS[lang] @@ -81,7 +81,7 @@ test('default loaders', () => { }) test('production defaults', () => { - const config = genConfig({}, 'production') + const config = genConfig({ postcss: {}}, 'production') const extractLoaderPath = require.resolve('extract-text-webpack-plugin/dist/loader') LANGS.forEach(lang => { const loader = lang === 'css' ? [] : LOADERS[lang] @@ -124,6 +124,7 @@ test('css.extract', () => { test('css.sourceMap', () => { const config = genConfig({ + postcss: {}, vue: { css: { sourceMap: true @@ -158,3 +159,11 @@ test('css.loaderOptions', () => { expect(findOptions(config, 'sass', 'sass')).toEqual({ data, indentedSyntax: true, sourceMap: false }) expect(findOptionsForVue(config, 'sass', 'sass')).toEqual({ data, indentedSyntax: true, sourceMap: false }) }) + +test('skip postcss-loader if no postcss config found', () => { + const config = genConfig() + LANGS.forEach(lang => { + const loader = lang === 'css' ? [] : LOADERS[lang] + expect(findLoaders(config, lang)).toEqual(['vue-style', 'css'].concat(loader)) + }) +}) diff --git a/packages/@vue/cli-service/lib/config/css.js b/packages/@vue/cli-service/lib/config/css.js index ba1700d130..aa53a497a0 100644 --- a/packages/@vue/cli-service/lib/config/css.js +++ b/packages/@vue/cli-service/lib/config/css.js @@ -1,3 +1,14 @@ +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 CSSLoaderResolver = require('../webpack/CSSLoaderResolver') @@ -6,9 +17,22 @@ module.exports = (api, options) => { const isProd = process.env.NODE_ENV === 'production' const userOptions = options.css || {} const extract = isProd && userOptions.extract !== false + + // 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 baseOptions = Object.assign({}, userOptions, { extract, - minimize: isProd + minimize: isProd, + postcss: hasPostCSSConfig }) const resolver = new CSSLoaderResolver(baseOptions) diff --git a/packages/@vue/cli-service/lib/webpack/CSSLoaderResolver.js b/packages/@vue/cli-service/lib/webpack/CSSLoaderResolver.js index 2e29dd6cf8..6668a0bb97 100644 --- a/packages/@vue/cli-service/lib/webpack/CSSLoaderResolver.js +++ b/packages/@vue/cli-service/lib/webpack/CSSLoaderResolver.js @@ -15,6 +15,7 @@ module.exports = class CSSLoaderResolver { * @param {boolean} [options.modules=undefined] Enable CSS modules. * @param {boolean} [options.extract=undefined] Extract CSS. * @param {boolean} [options.minimize=undefined] Minimize CSS. + * @param {boolean} [options.postcss=undefined] Enable postcss-loader. * @param {Object} [options.loaderOptions={}] Options to pass on to loaders. */ constructor ({ @@ -22,15 +23,16 @@ module.exports = class CSSLoaderResolver { modules, extract, minimize, + postcss, loaderOptions } = {}) { - this.postcss = true // true by default, turned off if generating for vue-loader this.cssLoader = 'css-loader' this.fallbackLoader = 'vue-style-loader' this.sourceMap = sourceMap this.extract = extract this.minimize = minimize this.modules = modules + this.postcss = postcss this.loaderOptions = loaderOptions || {} }