update to webpack4

This commit is contained in:
Pan 2018-07-19 18:02:48 +08:00
parent e254fc6c1a
commit 6ab4e59752
4 changed files with 127 additions and 144 deletions

View File

@ -1,13 +1,13 @@
'use strict' 'use strict'
const path = require('path') const path = require('path')
const config = require('../config') const config = require('../config')
const ExtractTextPlugin = require('extract-text-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const packageConfig = require('../package.json') const packageConfig = require('../package.json')
exports.assetsPath = function (_path) { exports.assetsPath = function (_path) {
const assetsSubDirectory = process.env.NODE_ENV === 'production' const assetsSubDirectory = process.env.NODE_ENV === 'production' ?
? config.build.assetsSubDirectory config.build.assetsSubDirectory :
: config.dev.assetsSubDirectory config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path) return path.posix.join(assetsSubDirectory, _path)
} }
@ -31,7 +31,21 @@ exports.cssLoaders = function (options) {
// generate loader string to be used with extract text plugin // generate loader string to be used with extract text plugin
function generateLoaders(loader, loaderOptions) { function generateLoaders(loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] const loaders = []
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
loaders.push(MiniCssExtractPlugin.loader)
} else {
loaders.push('vue-style-loader')
}
loaders.push(cssLoader)
if (options.usePostCSS) {
loaders.push(postcssLoader)
}
if (loader) { if (loader) {
loaders.push({ loaders.push({
@ -42,24 +56,16 @@ exports.cssLoaders = function (options) {
}) })
} }
// Extract CSS when that option is specified return loaders
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader'
})
} else {
return ['vue-style-loader'].concat(loaders)
} }
}
// https://vue-loader.vuejs.org/en/configurations/extract-css.html // https://vue-loader.vuejs.org/en/configurations/extract-css.html
return { return {
css: generateLoaders(), css: generateLoaders(),
postcss: generateLoaders(), postcss: generateLoaders(),
less: generateLoaders('less'), less: generateLoaders('less'),
sass: generateLoaders('sass', { indentedSyntax: true }), sass: generateLoaders('sass', {
indentedSyntax: true
}),
scss: generateLoaders('sass'), scss: generateLoaders('sass'),
stylus: generateLoaders('stylus'), stylus: generateLoaders('stylus'),
styl: generateLoaders('stylus') styl: generateLoaders('stylus')

View File

@ -17,6 +17,7 @@ const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT) const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, { const devWebpackConfig = merge(baseWebpackConfig, {
mode: 'development',
module: { module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
}, },
@ -47,8 +48,6 @@ const devWebpackConfig = merge(baseWebpackConfig, {
'process.env': require('../config/dev.env') 'process.env': require('../config/dev.env')
}), }),
new webpack.HotModuleReplacementPlugin(), new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin // https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
filename: 'index.html', filename: 'index.html',

View File

@ -7,8 +7,8 @@ const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf') const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin') const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
function resolve(dir) { function resolve(dir) {
@ -18,6 +18,7 @@ function resolve (dir) {
const env = require('../config/' + process.env.env_config + '.env') const env = require('../config/' + process.env.env_config + '.env')
const webpackConfig = merge(baseWebpackConfig, { const webpackConfig = merge(baseWebpackConfig, {
mode: 'production',
module: { module: {
rules: utils.styleLoaders({ rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap, sourceMap: config.build.productionSourceMap,
@ -29,36 +30,16 @@ const webpackConfig = merge(baseWebpackConfig, {
output: { output: {
path: config.build.assetsRoot, path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'), filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
}, },
plugins: [ plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html // http://vuejs.github.io/vue-loader/en/workflow/production.html
new webpack.DefinePlugin({ new webpack.DefinePlugin({
'process.env': env 'process.env': env
}), }),
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file // extract css into its own file
new ExtractTextPlugin({ new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'), filename: utils.assetsPath('css/[name].[chunkhash].css'),
// Setting the following option to `false` will not extract CSS from codesplit chunks.
// Their CSS will instead be inserted dynamically with style-loader when the codesplit chunk has been loaded by webpack.
// increasing file size: https://github.com/vuejs-templates/webpack/issues/1110
allChunks: false,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}), }),
// generate dist index.html with correct asset hash for caching. // generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html // you can customize output by editing /index.html
@ -77,76 +58,72 @@ const webpackConfig = merge(baseWebpackConfig, {
// more options: // more options:
// https://github.com/kangax/html-minifier#options-quick-reference // https://github.com/kangax/html-minifier#options-quick-reference
}, },
// necessary to consistently work with multiple chunks via CommonsChunkPlugin // default sort mode uses toposort which cannot handle cyclic deps
chunksSortMode: 'dependency' // in certain cases, and in webpack 4, chunk order in HTML doesn't
// matter anyway
chunksSortMode: 'none'
}), }),
// keep module.id stable when vender modules does not change // keep module.id stable when vender modules does not change
new webpack.HashedModuleIdsPlugin(), new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// split echarts into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'echarts',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
}
}),
// split xlsx into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'xlsx',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('xlsx') >= 0);
}
}),
// split codemirror into its own file
new webpack.optimize.CommonsChunkPlugin({
async: 'codemirror',
minChunks(module) {
var context = module.context;
return context && (context.indexOf('codemirror') >= 0);
}
}),
// copy custom static assets // copy custom static assets
new CopyWebpackPlugin([ new CopyWebpackPlugin([{
{
from: path.resolve(__dirname, '../static'), from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory, to: config.build.assetsSubDirectory,
ignore: ['.*'] ignore: ['.*']
}])
],
optimization: {
splitChunks: {
chunks: 'all',
name: 'vendors',
cacheGroups: {
libs: {
name: 'libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial'
},
elementUI: {
name: 'chunk-elementUI',
priority: 20,
test: /[\\/]node_modules[\\/]element-ui[\\/]/
},
echarts: {
name: 'chunk-echarts',
priority: 20,
test: function (module) {
var context = module.context;
return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0)
}
},
xlsx: {
name: 'chunk-xlsx',
priority: 20,
test: /[\\/]node_modules[\\/]xlsx[\\/]/
},
codemirror: {
name: 'chunk-codemirror',
priority: 20,
test: /[\\/]node_modules[\\/]codemirror[\\/]/
},
}
},
runtimeChunk: 'single',
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false
}
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSAssetsPlugin()
],
} }
])
]
}) })
if (config.build.productionGzip) { if (config.build.productionGzip) {

View File

@ -33,14 +33,14 @@
"url": "https://github.com/PanJiaChen/vue-element-admin/issues" "url": "https://github.com/PanJiaChen/vue-element-admin/issues"
}, },
"dependencies": { "dependencies": {
"axios": "0.17.1", "axios": "0.18.0",
"clipboard": "1.7.1", "clipboard": "1.7.1",
"codemirror": "5.32.0", "codemirror": "5.32.0",
"connect": "3.6.6", "connect": "3.6.6",
"driver.js": "0.5.2", "driver.js": "0.5.2",
"dropzone": "5.2.0", "dropzone": "5.2.0",
"echarts": "3.8.5", "echarts": "3.8.5",
"element-ui": "2.3.2", "element-ui": "2.4.4",
"file-saver": "1.3.3", "file-saver": "1.3.3",
"font-awesome": "4.7.0", "font-awesome": "4.7.0",
"js-cookie": "2.2.0", "js-cookie": "2.2.0",
@ -65,54 +65,55 @@
"xlsx": "^0.11.16" "xlsx": "^0.11.16"
}, },
"devDependencies": { "devDependencies": {
"autoprefixer": "7.2.3", "autoprefixer": "8.5.0",
"babel-core": "6.26.0", "babel-core": "6.26.0",
"babel-eslint": "8.0.3", "babel-eslint": "8.2.6",
"babel-helper-vue-jsx-merge-props": "2.0.3", "babel-helper-vue-jsx-merge-props": "2.0.3",
"babel-loader": "7.1.2", "babel-loader": "7.1.5",
"babel-plugin-dynamic-import-node": "^1.2.0", "babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-syntax-jsx": "6.18.0", "babel-plugin-syntax-jsx": "6.18.0",
"babel-plugin-transform-runtime": "6.23.0", "babel-plugin-transform-runtime": "6.23.0",
"babel-plugin-transform-vue-jsx": "3.5.0", "babel-plugin-transform-vue-jsx": "3.7.0",
"babel-preset-env": "1.6.1", "babel-preset-env": "1.7.0",
"babel-preset-stage-2": "6.24.1", "babel-preset-stage-2": "6.24.1",
"chalk": "2.3.0", "chalk": "2.4.1",
"copy-webpack-plugin": "4.3.0", "copy-webpack-plugin": "4.5.2",
"cross-env": "5.1.1", "cross-env": "5.1.1",
"css-loader": "0.28.7", "css-loader": "0.28.7",
"eslint": "4.13.1", "eslint": "4.19.1",
"eslint-friendly-formatter": "3.0.0", "eslint-friendly-formatter": "4.0.1",
"eslint-loader": "1.9.0", "eslint-loader": "2.0.0",
"eslint-plugin-html": "4.0.1", "eslint-plugin-html": "4.0.5",
"extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.11",
"file-loader": "1.1.5",
"friendly-errors-webpack-plugin": "1.6.1", "friendly-errors-webpack-plugin": "1.6.1",
"html-webpack-plugin": "2.30.1", "html-webpack-plugin": "3.2.0",
"husky": "0.14.3", "husky": "0.14.3",
"lint-staged": "7.2.0", "lint-staged": "7.2.0",
"node-notifier": "5.1.2", "mini-css-extract-plugin": "0.4.1",
"node-notifier": "5.2.1",
"node-sass": "^4.7.2", "node-sass": "^4.7.2",
"optimize-css-assets-webpack-plugin": "3.2.0", "optimize-css-assets-webpack-plugin": "5.0.0",
"ora": "1.3.0", "ora": "2.1.0",
"portfinder": "1.0.13", "portfinder": "1.0.13",
"postcss-import": "11.0.0", "postcss-import": "11.0.0",
"postcss-loader": "2.0.9", "postcss-loader": "2.1.6",
"postcss-url": "7.3.0", "postcss-url": "7.3.2",
"rimraf": "2.6.2", "rimraf": "2.6.2",
"sass-loader": "6.0.6", "sass-loader": "7.0.3",
"script-loader": "0.7.2", "script-loader": "0.7.2",
"semver": "5.4.1", "semver": "5.5.0",
"shelljs": "0.7.8", "shelljs": "0.8.2",
"svg-sprite-loader": "3.5.2", "svg-sprite-loader": "3.8.0",
"uglifyjs-webpack-plugin": "1.1.3", "uglifyjs-webpack-plugin": "1.2.7",
"url-loader": "0.6.2", "url-loader": "1.0.1",
"vue-loader": "13.7.2", "vue-loader": "14.2.2",
"vue-style-loader": "3.0.3", "vue-style-loader": "3.0.3",
"vue-template-compiler": "2.5.10", "vue-template-compiler": "2.5.10",
"webpack": "3.10.0", "webpack": "4.16.1",
"webpack-bundle-analyzer": "2.9.1", "webpack-bundle-analyzer": "2.13.1",
"webpack-dev-server": "2.9.7", "webpack-cli": "3.0.8",
"webpack-merge": "4.1.1" "webpack-dev-server": "3.1.4",
"webpack-merge": "4.1.3"
}, },
"engines": { "engines": {
"node": ">= 4.0.0", "node": ">= 4.0.0",