mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-19 23:21:09 +00:00
[vue-loader] allow using builtin extractCSS functionality
This option is disabled by default and won't affect exiting users. However users can easily enable this option using `nuxt.build.extractCSS` Implementation is according to: - https://github.com/vuejs/vue-loader/tree/master/docs/en/configurations - https://ssr.vuejs.org/en/css.html - https://github.com/vuejs/vue-hackernews-2.0/tree/master/build
This commit is contained in:
parent
379fb753ca
commit
87172100c7
@ -1,6 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
build: {
|
build: {
|
||||||
filenames: {
|
filenames: {
|
||||||
|
css: 'styles.[chunkhash].css', // default: common.[chunkhash].css
|
||||||
manifest: 'manifest.[hash].js', // default: manifest.[hash].js
|
manifest: 'manifest.[hash].js', // default: manifest.[hash].js
|
||||||
vendor: 'vendor.[hash].js', // default: vendor.bundle.[hash].js
|
vendor: 'vendor.[hash].js', // default: vendor.bundle.[hash].js
|
||||||
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
|
app: 'app.[chunkhash].js' // default: nuxt.bundle.[chunkhash].js
|
||||||
|
@ -51,6 +51,7 @@ const defaults = {
|
|||||||
analyze: false,
|
analyze: false,
|
||||||
publicPath: '/_nuxt/',
|
publicPath: '/_nuxt/',
|
||||||
filenames: {
|
filenames: {
|
||||||
|
css: 'common.[chunkhash].css',
|
||||||
manifest: 'manifest.[hash].js',
|
manifest: 'manifest.[hash].js',
|
||||||
vendor: 'vendor.bundle.[hash].js',
|
vendor: 'vendor.bundle.[hash].js',
|
||||||
app: 'nuxt.bundle.[chunkhash].js'
|
app: 'nuxt.bundle.[chunkhash].js'
|
||||||
|
@ -4,6 +4,8 @@ import vueLoaderConfig from './vue-loader.config'
|
|||||||
import { defaults } from 'lodash'
|
import { defaults } from 'lodash'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { isUrl, urlJoin } from '../utils'
|
import { isUrl, urlJoin } from '../utils'
|
||||||
|
import { styleLoader, extractStyles } from './helpers'
|
||||||
|
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
@ -71,15 +73,21 @@ export default function ({ isClient, isServer }) {
|
|||||||
cacheDirectory: !!this.dev
|
cacheDirectory: !!this.dev
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ test: /\.css$/, loader: 'vue-style-loader!css-loader' },
|
{ test: /\.css$/, use: styleLoader.call(this, 'css') },
|
||||||
{ test: /\.less$/, loader: 'vue-style-loader!css-loader!less-loader' },
|
{ test: /\.less$/, use: styleLoader.call(this, 'less', 'less-loader') },
|
||||||
{ test: /\.sass$/, loader: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' },
|
{ test: /\.sass$/, use: styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax') },
|
||||||
{ test: /\.scss$/, loader: 'vue-style-loader!css-loader!sass-loader' },
|
{ test: /\.scss$/, use: styleLoader.call(this, 'sass', 'sass-loader') },
|
||||||
{ test: /\.styl(us)?$/, loader: 'vue-style-loader!css-loader!stylus-loader' }
|
{ test: /\.styl(us)?$/, use: styleLoader.call(this, 'stylus', 'stylus-loader') }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
plugins: this.options.build.plugins
|
plugins: this.options.build.plugins
|
||||||
}
|
}
|
||||||
|
// CSS extraction
|
||||||
|
if (extractStyles.call(this)) {
|
||||||
|
config.plugins.push(
|
||||||
|
new ExtractTextPlugin({filename: this.options.build.filenames.css})
|
||||||
|
)
|
||||||
|
}
|
||||||
// Add nuxt build loaders (can be configured in nuxt.config.js)
|
// Add nuxt build loaders (can be configured in nuxt.config.js)
|
||||||
config.module.rules = config.module.rules.concat(this.options.build.loaders)
|
config.module.rules = config.module.rules.concat(this.options.build.loaders)
|
||||||
// Return config
|
// Return config
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
import { each, defaults } from 'lodash'
|
import { each, defaults } from 'lodash'
|
||||||
import webpack from 'webpack'
|
import webpack from 'webpack'
|
||||||
import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'
|
import VueSSRClientPlugin from 'vue-server-renderer/client-plugin'
|
||||||
|
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
||||||
import HTMLPlugin from 'html-webpack-plugin'
|
import HTMLPlugin from 'html-webpack-plugin'
|
||||||
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
|
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
|
||||||
import ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
import ProgressBarPlugin from 'progress-bar-webpack-plugin'
|
||||||
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
|
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'
|
||||||
import OfflinePlugin from 'offline-plugin'
|
import OfflinePlugin from 'offline-plugin'
|
||||||
import base from './base.config.js'
|
import base from './base.config.js'
|
||||||
|
import { extractStyles } from './helpers'
|
||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -55,9 +57,18 @@ export default function () {
|
|||||||
// Extract vendor chunks for better caching
|
// Extract vendor chunks for better caching
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
name: 'vendor',
|
name: 'vendor',
|
||||||
filename: this.options.build.filenames.vendor
|
filename: this.options.build.filenames.vendor,
|
||||||
|
minChunks (module) {
|
||||||
|
// A module is extracted into the vendor chunk when...
|
||||||
|
return (
|
||||||
|
// If it's inside node_modules
|
||||||
|
/node_modules/.test(module.context) &&
|
||||||
|
// Do not externalize if the request is a CSS file
|
||||||
|
!/\.css$/.test(module.request)
|
||||||
|
)
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
// Extract manifest
|
// Extract webpack runtime & manifest
|
||||||
new webpack.optimize.CommonsChunkPlugin({
|
new webpack.optimize.CommonsChunkPlugin({
|
||||||
name: 'manifest',
|
name: 'manifest',
|
||||||
minChunks: Infinity,
|
minChunks: Infinity,
|
||||||
@ -68,6 +79,7 @@ export default function () {
|
|||||||
template: this.options.appTemplatePath,
|
template: this.options.appTemplatePath,
|
||||||
inject: false // <- Resources will be injected using vue server renderer
|
inject: false // <- Resources will be injected using vue server renderer
|
||||||
}),
|
}),
|
||||||
|
// Generate client manifest json
|
||||||
new VueSSRClientPlugin({
|
new VueSSRClientPlugin({
|
||||||
filename: 'client-manifest.json'
|
filename: 'client-manifest.json'
|
||||||
})
|
})
|
||||||
|
15
lib/webpack/helpers.js
Executable file
15
lib/webpack/helpers.js
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
import ExtractTextPlugin from 'extract-text-webpack-plugin'
|
||||||
|
|
||||||
|
export function extractStyles(ext) {
|
||||||
|
return !this.dev && !!this.options.build.extractCSS && this.options.build.extractCSS[ext] !== false
|
||||||
|
}
|
||||||
|
|
||||||
|
export function styleLoader(ext, loader = []) {
|
||||||
|
if (!extractStyles.call(this, ext)) {
|
||||||
|
return ['vue-style-loader', 'css-loader'].concat(loader)
|
||||||
|
}
|
||||||
|
return ExtractTextPlugin.extract({
|
||||||
|
use: ['css-loader?minimize'].concat(loader),
|
||||||
|
fallback: 'vue-style-loader'
|
||||||
|
})
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
import { defaults } from 'lodash'
|
import { defaults } from 'lodash'
|
||||||
|
import { extractStyles, styleLoader } from './helpers'
|
||||||
|
|
||||||
export default function ({ isClient }) {
|
export default function ({ isClient }) {
|
||||||
let babelOptions = JSON.stringify(defaults(this.options.build.babel, {
|
let babelOptions = JSON.stringify(defaults(this.options.build.babel, {
|
||||||
@ -8,18 +9,21 @@ export default function ({ isClient }) {
|
|||||||
babelrc: false,
|
babelrc: false,
|
||||||
cacheDirectory: !!this.dev
|
cacheDirectory: !!this.dev
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
// https://github.com/vuejs/vue-loader/blob/master/docs/en/configurations
|
||||||
let config = {
|
let config = {
|
||||||
postcss: this.options.build.postcss,
|
postcss: this.options.build.postcss,
|
||||||
loaders: {
|
loaders: {
|
||||||
'js': 'babel-loader?' + babelOptions,
|
'js': 'babel-loader?' + babelOptions,
|
||||||
'css': 'vue-style-loader!css-loader',
|
'css': styleLoader.call(this, 'css'),
|
||||||
'less': 'vue-style-loader!css-loader!less-loader',
|
'less': styleLoader.call(this, 'less', 'less-loader'),
|
||||||
'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax',
|
'sass': styleLoader.call(this, 'sass', 'sass-loader?indentedSyntax'),
|
||||||
'scss': 'vue-style-loader!css-loader!sass-loader',
|
'scss': styleLoader.call(this, 'sass', 'scss-loader'),
|
||||||
'stylus': 'vue-style-loader!css-loader!stylus-loader',
|
'stylus': styleLoader.call(this, 'stylus', 'stylus-loader'),
|
||||||
'styl': 'vue-style-loader!css-loader!stylus-loader'
|
'styl': styleLoader.call(this, 'stylus', 'stylus-loader')
|
||||||
},
|
},
|
||||||
preserveWhitespace: false
|
preserveWhitespace: false,
|
||||||
|
extractCSS: extractStyles.call(this, 'vue')
|
||||||
}
|
}
|
||||||
// Return the config
|
// Return the config
|
||||||
return config
|
return config
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
"compression": "^1.6.2",
|
"compression": "^1.6.2",
|
||||||
"css-loader": "^0.28.0",
|
"css-loader": "^0.28.0",
|
||||||
"debug": "^2.6.6",
|
"debug": "^2.6.6",
|
||||||
|
"extract-text-webpack-plugin": "^2.1.0",
|
||||||
"file-loader": "^0.11.1",
|
"file-loader": "^0.11.1",
|
||||||
"friendly-errors-webpack-plugin": "^1.6.1",
|
"friendly-errors-webpack-plugin": "^1.6.1",
|
||||||
"fs-extra": "^3.0.0",
|
"fs-extra": "^3.0.0",
|
||||||
|
Loading…
Reference in New Issue
Block a user