From ef5b910112af8477ac8fd2cabaf5ae76ee45b0e6 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 28 Dec 2017 19:35:34 +0330 Subject: [PATCH] refactor postcssConfig --- lib/builder/builder.js | 14 ----- lib/builder/webpack/postcss.js | 74 ++++++++++++++++++++++++ lib/builder/webpack/style-loader.js | 14 +++-- lib/builder/webpack/vue-loader.config.js | 4 +- lib/common/options.js | 63 -------------------- 5 files changed, 86 insertions(+), 83 deletions(-) create mode 100644 lib/builder/webpack/postcss.js diff --git a/lib/builder/builder.js b/lib/builder/builder.js index 832b5fd0a4..16fa8b0fd1 100644 --- a/lib/builder/builder.js +++ b/lib/builder/builder.js @@ -118,20 +118,6 @@ module.exports = class Builder { // Call before hook await this.nuxt.callHook('build:before', this, this.options.build) - // Map postcss plugins into instances on object mode once - if (isPureObject(this.options.build.postcss)) { - if (isPureObject(this.options.build.postcss.plugins)) { - this.options.build.postcss.plugins = Object.keys(this.options.build.postcss.plugins) - .map(p => { - const plugin = require(this.nuxt.resolvePath(p)) - const opts = this.options.build.postcss.plugins[p] - if (opts === false) return // Disabled - const instance = plugin(opts) - return instance - }).filter(e => e) - } - } - // Check if pages dir exists and warn if not this._nuxtPages = typeof this.options.build.createRoutes !== 'function' if (this._nuxtPages) { diff --git a/lib/builder/webpack/postcss.js b/lib/builder/webpack/postcss.js new file mode 100644 index 0000000000..ee699b4c3f --- /dev/null +++ b/lib/builder/webpack/postcss.js @@ -0,0 +1,74 @@ +const { existsSync } = require('fs') +const { resolve } = require('path') +const debug = require('debug')('nuxt:postcss') +const { isPureObject } = require('../../common/utils') +const { cloneDeep } = require('lodash') + +module.exports = function postcssConfig() { + let config = cloneDeep(this.options.build.postcss) + + if (!config) { + return false + } + + // Search for postCSS config file and use it if exists + // https://github.com/michael-ciniawsky/postcss-load-config + for (let dir of [this.options.srcDir, this.options.rootDir]) { + for (let file of ['postcss.config.js', '.postcssrc.js', '.postcssrc', '.postcssrc.json', '.postcssrc.yaml']) { + if (existsSync(resolve(dir, file))) { + const postcssConfigPath = resolve(dir, file) + debug(`Using config file: ${postcssConfigPath}`) + return { + sourceMap: this.options.build.cssSourceMap, + config: { + path: postcssConfigPath + } + } + } + } + } + + // Normalize + if (Array.isArray(config)) { + config = { plugins: config } + } + + // Apply default plugins + if (isPureObject(config)) { + config = Object.assign({ + useConfigFile: false, + sourceMap: this.options.build.cssSourceMap, + plugins: { + // https://github.com/postcss/postcss-import + 'postcss-import': { + root: this.options.rootDir, + path: [ + this.options.srcDir, + this.options.rootDir, + ...this.options.modulesDir + ] + }, + + // https://github.com/postcss/postcss-url + 'postcss-url': {}, + + // http://cssnext.io/postcss + 'postcss-cssnext': {} + } + }, config) + } + + // Map postcss plugins into instances on object mode once + if (isPureObject(config) && isPureObject(config.plugins)) { + config.plugins = Object.keys(config.plugins) + .map(p => { + const plugin = require(this.nuxt.resolvePath(p)) + const opts = config.plugins[p] + if (opts === false) return // Disabled + const instance = plugin(opts) + return instance + }).filter(e => e) + } + + return config +} diff --git a/lib/builder/webpack/style-loader.js b/lib/builder/webpack/style-loader.js index 5c4a8dee2f..dfcfe10f1f 100755 --- a/lib/builder/webpack/style-loader.js +++ b/lib/builder/webpack/style-loader.js @@ -1,5 +1,6 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin') const { join } = require('path') +const postcssConfig = require('./postcss') module.exports = function styleLoader(ext, loaders = [], isVueLoader = false) { const sourceMap = Boolean(this.options.build.cssSourceMap) @@ -29,11 +30,14 @@ module.exports = function styleLoader(ext, loaders = [], isVueLoader = false) { // postcss-loader // vue-loader already provides it's own // https://github.com/postcss/postcss-loader - if (!isVueLoader && this.options.build.postcss) { - loaders.unshift({ - loader: 'postcss-loader', - options: Object.assign({ sourceMap }, this.options.build.postcss) - }) + if (!isVueLoader) { + const _postcssConfig = postcssConfig.call(this) + if (_postcssConfig) { + loaders.unshift({ + loader: 'postcss-loader', + options: Object.assign({ sourceMap }, _postcssConfig) + }) + } } // css-loader diff --git a/lib/builder/webpack/vue-loader.config.js b/lib/builder/webpack/vue-loader.config.js index af162b1869..ed33271866 100644 --- a/lib/builder/webpack/vue-loader.config.js +++ b/lib/builder/webpack/vue-loader.config.js @@ -1,7 +1,9 @@ +const postcssConfig = require('./postcss') + module.exports = function vueLoader({ isServer }) { // https://vue-loader.vuejs.org/en const config = { - postcss: this.options.build.postcss, + postcss: postcssConfig.call(this), extractCSS: !!this.options.build.extractCSS, cssSourceMap: this.options.build.cssSourceMap, preserveWhitespace: false, diff --git a/lib/common/options.js b/lib/common/options.js index 3194c84b5c..e43a8d7506 100755 --- a/lib/common/options.js +++ b/lib/common/options.js @@ -91,69 +91,6 @@ Options.from = function (_options) { options.build.cssSourceMap = options.dev } - // Postcss - // 1. Check if it is explicitly disabled by false value - // ... Disable all postcss loaders - // 2. Check if any standard source of postcss config exists - // ... Make postcss = { config: { path } } - // 3. Else (Easy Usage) - // ... Auto merge it with defaults - if (options.build.postcss !== false) { - // Detect postcss config existence - // https://github.com/michael-ciniawsky/postcss-load-config - let postcssConfigPath - for (let dir of [options.srcDir, options.rootDir]) { - for (let file of ['postcss.config.js', '.postcssrc.js', '.postcssrc', '.postcssrc.json', '.postcssrc.yaml']) { - if (existsSync(resolve(dir, file))) { - postcssConfigPath = resolve(dir, file) - break - } - } - if (postcssConfigPath) break - } - - // Default postcss options - if (postcssConfigPath) { - debug(`Using PostCSS config file: ${postcssConfigPath}`) - options.build.postcss = { - sourceMap: options.build.cssSourceMap, - // https://github.com/postcss/postcss-loader/blob/master/lib/index.js#L79 - config: { - path: postcssConfigPath - } - } - } else { - if (Object.keys(options.build.postcss).length) { - debug('Using PostCSS config from `build.postcss`') - } - // Normalize & Apply default plugins - if (Array.isArray(options.build.postcss)) { - options.build.postcss = { plugins: options.build.postcss } - } - if (isPureObject(options.build.postcss)) { - options.build.postcss = Object.assign({ - useConfigFile: false, - sourceMap: options.build.cssSourceMap, - plugins: { - // https://github.com/postcss/postcss-import - 'postcss-import': { - root: options.rootDir, - path: [ - options.srcDir, - options.rootDir, - ...options.modulesDir - ] - }, - // https://github.com/postcss/postcss-url - 'postcss-url': {}, - // http://cssnext.io/postcss - 'postcss-cssnext': {} - } - }, options.build.postcss) - } - } - } - // Debug errors if (options.debug === undefined) { options.debug = options.dev