Skip to content

Commit

Permalink
working postcss everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
Pooya Parsa committed Aug 14, 2017
1 parent 48b5ff3 commit 5d24294
Show file tree
Hide file tree
Showing 8 changed files with 328 additions and 97 deletions.
25 changes: 25 additions & 0 deletions lib/builder/builder.js
Expand Up @@ -15,6 +15,9 @@ import Debug from 'debug'
import Glob from 'glob'
import clientWebpackConfig from './webpack/client.config.js'
import serverWebpackConfig from './webpack/server.config.js'
import autoprefixer from 'autoprefixer'
import vueLoaderConfig from './webpack/vue-loader.config'
import styleLoader from './webpack/style-loader'

const debug = Debug('nuxt:build')
debug.color = 2 // Force green color
Expand Down Expand Up @@ -48,6 +51,28 @@ export default class Builder extends Tapable {
// Helper to resolve build paths
this.relativeToBuild = (...args) => relativeTo(this.options.buildDir, ...args)

// Enable autoprefixer if both autoprefixer postcss are enabled
if (this.options.build.autoprefixer && this.options.build.postcss) {
const plugin = autoprefixer(this.options.build.autoprefixer)
const plugins = this.options.build.postcss.plugins || this.options.build.postcss
if (Array.isArray(plugins)) {
plugins.push(plugin)
}
}

// Bind styleLoader and vueLoader
this.styleLoader = styleLoader.bind(this)
this.vueLoader = vueLoaderConfig.bind(this)

// Babel options
this.babelOptions = _.defaults(this.options.build.babel, {
presets: [
require.resolve('babel-preset-vue-app')
],
babelrc: false,
cacheDirectory: !!this.options.dev
})

this._buildStatus = STATUS.INITIAL
}

Expand Down
46 changes: 17 additions & 29 deletions lib/builder/webpack/base.config.js
@@ -1,11 +1,8 @@
import ExtractTextPlugin from 'extract-text-webpack-plugin'
import { defaults, cloneDeep } from 'lodash'
import { cloneDeep } from 'lodash'
import { join, resolve } from 'path'
import webpack from 'webpack'
import { isUrl, urlJoin } from 'utils'
import autoprefixer from 'autoprefixer'
import vueLoaderConfig from './vue-loader.config'
import { styleLoader, extractStyles } from './helpers'

/*
|--------------------------------------------------------------------------
Expand All @@ -18,11 +15,6 @@ import { styleLoader, extractStyles } from './helpers'
export default function webpackBaseConfig ({ isClient, isServer }) {
const nodeModulesDir = join(__dirname, '..', 'node_modules')

// Enable autoprefixer if both autoprefixer postcss are enabled
if (this.options.build.autoprefixer && Array.isArray(this.options.build.postcss)) {
this.options.build.postcss.push(autoprefixer(this.options.build.autoprefixer))
}

const config = {
devtool: this.options.dev ? 'cheap-module-source-map' : 'nosources-source-map',
entry: {
Expand Down Expand Up @@ -66,48 +58,44 @@ export default function webpackBaseConfig ({ isClient, isServer }) {
]
},
module: {
noParse: /es6-promise\.js$/, // avoid webpack shimming process
noParse: /es6-promise\.js$/, // Avoid webpack shimming process
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
query: vueLoaderConfig.call(this, { isClient, isServer })
options: this.vueLoader({ isClient, isServer })
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: defaults(this.options.build.babel, {
presets: [require.resolve('babel-preset-vue-app')],
babelrc: false,
cacheDirectory: !!this.options.dev
})
options: Object.assign({}, this.babelOptions)
},
{ test: /\.css$/, use: styleLoader.call(this, 'css') },
{ test: /\.less$/, use: styleLoader.call(this, 'less', 'less-loader') },
{ test: /\.sass$/, use: styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax&sourceMap') },
{ test: /\.scss$/, use: styleLoader.call(this, 'sass', 'sass-loader?sourceMap') },
{ test: /\.styl(us)?$/, use: styleLoader.call(this, 'stylus', 'stylus-loader') },
{ test: /\.css$/, use: this.styleLoader('css') },
{ test: /\.less$/, use: this.styleLoader('less', 'less-loader') },
{ test: /\.sass$/, use: this.styleLoader('sass', 'sass-loader?indentedSyntax') },
{ test: /\.scss$/, use: this.styleLoader('scss', 'sass-loader') },
{ test: /\.styl(us)?$/, use: this.styleLoader('stylus', 'stylus-loader') },
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
query: {
options: {
limit: 1000, // 1KO
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
options: {
limit: 1000, // 1 KO
name: 'fonts/[name].[hash:7].[ext]'
}
},
{
test: /\.(webm|mp4)$/,
loader: 'file',
query: {
loader: 'file-loader',
options: {
name: 'videos/[name].[hash:7].[ext]'
}
}
Expand All @@ -117,10 +105,10 @@ export default function webpackBaseConfig ({ isClient, isServer }) {
}

// CSS extraction
if (extractStyles.call(this)) {
config.plugins.push(
new ExtractTextPlugin({ filename: this.options.build.filenames.css })
)
if (this.options.build.extractCSS) {
config.plugins.push(new ExtractTextPlugin({
filename: this.options.build.filenames.css
}))
}

// Workaround for hiding Warnings about plugins without a default export (#1179)
Expand Down
40 changes: 0 additions & 40 deletions lib/builder/webpack/helpers.js

This file was deleted.

80 changes: 80 additions & 0 deletions lib/builder/webpack/style-loader.js
@@ -0,0 +1,80 @@
import ExtractTextPlugin from 'extract-text-webpack-plugin'
import { join } from 'path'

export default function styleLoader (ext, loaders = [], isVueLoader = false) {
// Normalize loaders
loaders = (Array.isArray(loaders) ? loaders : [loaders]).map(loader => {
if (typeof loader === 'string') {
return {
loader,
options: {
// Source map is REQUIRED for urlLoader
sourceMap: true
}
}
}
return loader
})

// https://github.com/postcss/postcss-loader
let postcssLoader
let postcssPlugins = this.options.build.postcss
if (!isVueLoader && Array.isArray(postcssPlugins) && postcssPlugins.length) {
postcssLoader = {
loader: 'postcss-loader',
options: {
sourceMap: this.options.build.cssSourceMap,
plugins: () => postcssPlugins,
config: {}
}
}
}

// https://github.com/webpack-contrib/css-loader
const cssLoader = {
loader: 'css-loader',
options: {
minimize: true,
importLoaders: 1,
sourceMap: this.options.build.cssSourceMap,
root: '~', // https://github.com/webpack/loader-utils#root-relative-urls
alias: {
'/static': join(this.options.srcDir, 'static'),
'/assets': join(this.options.srcDir, 'assets')
}
}
}

// https://github.com/vuejs/vue-style-loader
const vueStyleLoader = {
loader: 'vue-style-loader',
options: {
sourceMap: this.options.build.cssSourceMap
}
}

// https://github.com/bholloway/resolve-url-loader
const urlLoader = {
loader: 'resolve-url-loader'
}

if (this.options.build.extractCSS) {
return ExtractTextPlugin.extract({
fallback: vueStyleLoader,
use: [
cssLoader,
postcssLoader,
urlLoader,
...loaders
].filter(l => l)
})
}

return [
vueStyleLoader,
cssLoader,
postcssLoader,
urlLoader,
...loaders
].filter(l => l)
}
41 changes: 18 additions & 23 deletions lib/builder/webpack/vue-loader.config.js
@@ -1,31 +1,26 @@
import { defaults } from 'lodash'
import { extractStyles, styleLoader } from './helpers'

export default function ({ isClient }) {
let babelOptions = JSON.stringify(defaults(this.options.build.babel, {
presets: [require.resolve('babel-preset-vue-app')],
babelrc: false,
cacheDirectory: !!this.options.dev
}))

// https://github.com/vuejs/vue-loader/blob/master/docs/en/configurations
export default function vueLoader ({ isClient }) {
// https://vue-loader.vuejs.org/en
const config = {
postcss: this.options.build.postcss,
extractCSS: this.options.build.extractCSS,
cssSourceMap: this.options.build.cssSourceMap,
preserveWhitespace: false,
loaders: {
'js': 'babel-loader?' + babelOptions,
'css': styleLoader.call(this, 'css'),
'less': styleLoader.call(this, 'less', 'less-loader'),
'sass': styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax&sourceMap'),
'scss': styleLoader.call(this, 'sass', 'sass-loader?sourceMap'),
'stylus': styleLoader.call(this, 'stylus', 'stylus-loader'),
'styl': styleLoader.call(this, 'stylus', 'stylus-loader')
'js': {
loader: 'babel-loader',
options: Object.assign({}, this.babelOptions)
},
// Note: do not nest the `postcss` option under `loaders`
'css': this.styleLoader('css', [], true),
'less': this.styleLoader('less', 'less-loader', true),
'scss': this.styleLoader('scss', 'sass-loader', true),
'sass': this.styleLoader('sass', 'sass-loader?indentedSyntax', true),
'stylus': this.styleLoader('stylus', 'stylus-loader', true),
'styl': this.styleLoader('stylus', 'stylus-loader', true)
},
template: {
// for pug, see https://github.com/vuejs/vue-loader/issues/55
doctype: 'html'
},
preserveWhitespace: false,
extractCSS: extractStyles.call(this)
doctype: 'html' // For pug, see https://github.com/vuejs/vue-loader/issues/55
}
}

// Return the config
Expand Down
1 change: 1 addition & 0 deletions lib/common/options.js
Expand Up @@ -104,6 +104,7 @@ Options.defaults = {
build: {
analyze: false,
extractCSS: false,
cssSourceMap: true,
ssr: undefined,
publicPath: '/_nuxt/',
filenames: {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -97,8 +97,10 @@
"minimist": "^1.2.0",
"opencollective": "^1.0.3",
"pify": "^3.0.0",
"postcss-loader": "^2.0.6",
"pretty-error": "^2.1.1",
"progress-bar-webpack-plugin": "^1.10.0",
"resolve-url-loader": "^2.1.0",
"serialize-javascript": "^1.4.0",
"serve-static": "^1.12.4",
"server-destroy": "^1.0.1",
Expand Down

0 comments on commit 5d24294

Please sign in to comment.