From 3cf31f7cff3190b477bd4099a769fb85fbd40916 Mon Sep 17 00:00:00 2001 From: James ZHANG Date: Mon, 26 Mar 2018 13:22:16 +0800 Subject: [PATCH] [optim] based on utils.resovle, add `hard-source-webpack-plugin` for `run build:prod` speedup --- build/utils.js | 4 ++++ build/webpack.base.conf.js | 41 ++++++++++++++++++++++++++------------ build/webpack.dev.conf.js | 9 ++------- build/webpack.prod.conf.js | 28 +++++++++++++++++--------- package.json | 3 ++- 5 files changed, 55 insertions(+), 30 deletions(-) diff --git a/build/utils.js b/build/utils.js index e534fb0f..f0dd3c5a 100644 --- a/build/utils.js +++ b/build/utils.js @@ -99,3 +99,7 @@ exports.createNotifierCallback = () => { }) } } + +exports.resolve = (dir) => { + return path.join(__dirname, '..', dir) +} \ No newline at end of file diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js index 97bc6e2b..bc0c10dc 100644 --- a/build/webpack.base.conf.js +++ b/build/webpack.base.conf.js @@ -1,18 +1,13 @@ 'use strict' -const path = require('path') const utils = require('./utils') const config = require('../config') const vueLoaderConfig = require('./vue-loader.conf') -function resolve (dir) { - return path.join(__dirname, '..', dir) -} - const createLintingRule = () => ({ test: /\.(js|vue)$/, loader: 'eslint-loader', enforce: 'pre', - include: [resolve('src'), resolve('test')], + include: [utils.resolve('src'), utils.resolve('test')], options: { formatter: require('eslint-friendly-formatter'), emitWarning: !config.dev.showEslintErrorsInOverlay @@ -20,9 +15,9 @@ const createLintingRule = () => ({ }) module.exports = { - context: path.resolve(__dirname, '../'), + context: utils.resolve(''), entry: { - app: './src/main.js' + app: utils.resolve('src/main.js') }, output: { path: config.build.assetsRoot, @@ -32,10 +27,29 @@ module.exports = { : config.dev.assetsPublicPath }, resolve: { + modules: [utils.resolve('node_modules')], extensions: ['.js', '.vue', '.json'], alias: { - 'vue$': 'vue/dist/vue.esm.js', - '@': resolve('src'), + 'vue$': utils.resolve('node_modules/vue/dist/vue.esm.js'), + + 'vue-count-to': utils.resolve('node_modules/vue-count-to/dist/vue-count-to.min.js'), + 'vue-hot-reload-api': utils.resolve('node_modules/vue-hot-reload-api/dist/index.js'), + 'vue-i18n': utils.resolve('node_modules/vue-i18n/dist/vue-i18n.esm.js'), + 'vue-loader': utils.resolve('node_modules/vue-loader/index.js'), + 'vue-router': utils.resolve('node_modules/vue-router/dist/vue-router.esm.js'), + 'vue-splitpane': utils.resolve('node_modules/vue-splitpane/dist/vue-split-pane.min.js'), + 'vue-style-loader': utils.resolve('node_modules/vue-style-loader/index.js'), + 'vue-template-compiler': utils.resolve('node_modules/vue-template-compiler/index.js'), + 'vue-template-es2015-compiler': utils.resolve('node_modules/vue-template-es2015-compiler/index.js'), + 'vuex': utils.resolve('node_modules/vuex/dist/vuex.esm.js'), + 'xlsx': utils.resolve('node_modules/xlsx/xlsx.js'), + 'screenfull': utils.resolve('node_modules/screenfull/dist/screenfull.js'), + 'mockjs': utils.resolve('node_modules/mockjs/dist/mock-min.js'), + 'jszip': utils.resolve('node_modules/jszip/dist/jszip.min.js'), + 'js-cookie': utils.resolve('node_modules/js-cookie/src/js.cookie.js'), + 'axios': utils.resolve('node_modules/axios/dist/axios.min.js'), + + '@': utils.resolve('src'), } }, module: { @@ -49,12 +63,13 @@ module.exports = { { test: /\.js$/, loader: 'babel-loader?cacheDirectory', - include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] + include: [utils.resolve('src'), utils.resolve('test'), utils.resolve('node_modules/webpack-dev-server/client')], + exclude: [utils.resolve('node_modules'), utils.resolve('src/vendor')], }, { test: /\.svg$/, loader: 'svg-sprite-loader', - include: [resolve('src/icons')], + include: [utils.resolve('src/icons')], options: { symbolId: 'icon-[name]' } @@ -62,7 +77,7 @@ module.exports = { { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', - exclude: [resolve('src/icons')], + exclude: [utils.resolve('src/icons')], options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js index 43901e5b..bf1a527e 100644 --- a/build/webpack.dev.conf.js +++ b/build/webpack.dev.conf.js @@ -1,5 +1,4 @@ 'use strict' -const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') @@ -9,10 +8,6 @@ const HtmlWebpackPlugin = require('html-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin') const portfinder = require('portfinder') -function resolve (dir) { - return path.join(__dirname, '..', dir) -} - const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) @@ -54,7 +49,7 @@ const devWebpackConfig = merge(baseWebpackConfig, { filename: 'index.html', template: 'index.html', inject: true, - favicon: resolve('favicon.ico'), + favicon: utils.resolve('favicon.ico'), title: 'vue-element-admin', path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory }), @@ -82,7 +77,7 @@ module.exports = new Promise((resolve, reject) => { : undefined })) - resolve(devWebpackConfig) + utils.resolve(devWebpackConfig) } }) }) diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js index 7f710543..e458e99a 100644 --- a/build/webpack.prod.conf.js +++ b/build/webpack.prod.conf.js @@ -1,5 +1,4 @@ 'use strict' -const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') @@ -10,14 +9,12 @@ const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') - -function resolve (dir) { - return path.join(__dirname, '..', dir) -} +const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') const env = require('../config/'+process.env.env_config+'.env') const webpackConfig = merge(baseWebpackConfig, { + cache: true, module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, @@ -32,6 +29,18 @@ const webpackConfig = merge(baseWebpackConfig, { chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, plugins: [ + new HardSourceWebpackPlugin({ + cacheDirectory: utils.resolve('node_modules/.cache/hard-source/[confighash]'), + configHash: (webpackConfig) => { + return require('node-object-hash')({sort: false}).hash(webpackConfig); + }, + environmentHash: { + root: process.cwd(), + directories: [], + files: ['package-lock.json', 'yarn.lock'], + }, + }), + // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env @@ -43,7 +52,8 @@ const webpackConfig = merge(baseWebpackConfig, { } }, sourceMap: config.build.productionSourceMap, - parallel: true + parallel: true, + cache: true, }), // extract css into its own file new ExtractTextPlugin({ @@ -67,7 +77,7 @@ const webpackConfig = merge(baseWebpackConfig, { filename: config.build.index, template: 'index.html', inject: true, - favicon: resolve('favicon.ico'), + favicon: utils.resolve('favicon.ico'), title: 'vue-element-admin', path: config.build.assetsPublicPath + config.build.assetsSubDirectory, minify: { @@ -93,7 +103,7 @@ const webpackConfig = merge(baseWebpackConfig, { module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( - path.join(__dirname, '../node_modules') + utils.resolve('node_modules') ) === 0 ) } @@ -141,7 +151,7 @@ const webpackConfig = merge(baseWebpackConfig, { // copy custom static assets new CopyWebpackPlugin([ { - from: path.resolve(__dirname, '../static'), + from: utils.resolve('static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } diff --git a/package.json b/package.json index 1d9ae8f3..71b451ce 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "vue-splitpane": "1.0.2", "vuedraggable": "2.15.0", "vuex": "3.0.1", - "xlsx": "^0.11.16" + "xlsx": "0.11.16" }, "devDependencies": { "autoprefixer": "7.2.3", @@ -63,6 +63,7 @@ "extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.5", "friendly-errors-webpack-plugin": "1.6.1", + "hard-source-webpack-plugin": "0.6.4", "html-webpack-plugin": "2.30.1", "node-notifier": "5.1.2", "node-sass": "^4.7.2",