build 文件夹中的 webpack.prod.conf.js

  1 // 此文件是生产环境下webpack相关配置
  2 'use strict'
  3 const path = require('path')
  4 const utils = require('./utils')
  5 const webpack = require('webpack')
  6 const config = require('../config') // 引入全局配置
  7 const merge = require('webpack-merge') // webpack-merge插件提供合并功能,将多个对象合并创建一个新对象。
  8 const baseWebpackConfig = require('./webpack.base.conf')
  9 const CopyWebpackPlugin = require('copy-webpack-plugin') // 用来复制
 10 const HtmlWebpackPlugin = require('html-webpack-plugin') // 自动生成html文件
 11 // const ExtractTextPlugin = require('extract-text-webpack-plugin') // 用来抽离css 防止css打包压缩到js中
 12 const MiniCssExtractPlugin = require('mini-css-extract-plugin') //将css单独打包成一个文件的插件,它为每个包含css的js文件都创建一个css文件
 13 const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') // 用来压缩单独的css文件
 14 const UglifyJsPlugin = require('uglifyjs-webpack-plugin') //用来压缩
 15 
 16 //导入prod.env.js 用来区分是生产环境
 17 const env = process.env.NODE_ENV === 'testing' ?
 18   require('../config/test.env') :
 19   require('../config/prod.env')
 20 
 21 // 合并
 22 const webpackConfig = merge(baseWebpackConfig, {
 23   mode: 'production',
 24   module: {
 25     // 配置独立的css文件的解析规则
 26     rules: utils.styleLoaders({
 27       sourceMap: config.build.productionSourceMap,
 28       // 生成独立的文件
 29       extract: true,
 30       usePostCSS: true
 31     })
 32   },
 33   // 开发工具 用来调试
 34   devtool: config.build.productionSourceMap ? config.build.devtool : false,
 35   // 输出
 36   output: {
 37     // 打包后的文件放在dist目录下面
 38     path: config.build.assetsRoot,
 39     // 编译生成的js文件存放在根目录下的js目录下,如果js文件夹不存在就自动创建
 40     filename: utils.assetsPath('js/[name].[chunkhash].js'),
 41     // 用来打包require.ensure方法中引入的模块,如果该方法中没有引入任何模块,就不会生成chunk文件
 42     chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
 43   },
 44   // 优化 (https://webpack.docschina.org/configuration/optimization/)
 45   optimization: {
 46     moduleIds: 'hashed', // 告知 webpack 当选择模块 id 时需要使用哪种算法 ( 'hashed' 相应地会在 webpack 5 中废弃,被 'deterministic' 代替 )
 47     // 拆分模块 (https://www.cnblogs.com/kwzm/p/10314438.html)
 48     splitChunks: {
 49       chunks: 'async', // 选择用于确定共享模块的块(默认为“async”、“initial”和“all”需要将这些块添加到HTML中)
 50       minSize: 30000, // 创建块的大小
 51       // minRemainingSize: 0,
 52       maxSize: 0,
 53       minChunks: 1,
 54       maxAsyncRequests: 6,
 55       maxInitialRequests: 4,
 56       automaticNameDelimiter: '~',
 57       cacheGroups: {
 58         defaultVendors: {
 59           test: /[\\/]node_modules[\\/]/,
 60           priority: -10
 61         },
 62         default: {
 63           minChunks: 2,
 64           priority: -20,
 65           reuseExistingChunk: true
 66         },
 67         elementUI: {
 68           name: "chunk-elementUI", // 单独将 elementUI 拆包
 69           priority: 15, // 权重需大于其它缓存组
 70           test: /[\/]node_modules[\/]element-ui[\/]/
 71         }
 72       }
 73     }
 74   },
 75   //配置插件项
 76   plugins: [
 77     // http://vuejs.github.io/vue-loader/en/workflow/production.html
 78     // 自定义一个plugin 生成当前环境下的一个变量
 79     new webpack.DefinePlugin({
 80       'process.env': env
 81     }),
 82     //压缩
 83     new UglifyJsPlugin({
 84       uglifyOptions: {
 85         // 禁止压缩警告信息
 86         warnings: false
 87       },
 88       sourceMap: config.build.productionSourceMap, //是否开启sourceMap 用来调试
 89       parallel: true //在系统的CPU有多于一个内核时自动启用 仅作用于生产构建
 90     }),
 91     // 将css解压缩到它自己的文件中
 92     new MiniCssExtractPlugin({
 93       //文件名
 94       filename: utils.assetsPath('css/app.[name].css'),
 95       chunkFilename: utils.assetsPath('css/app.[contenthash:12].css'), // use contenthash *
 96     }),
 97     //压缩提取CSS。我们使用这个插件,所以可以从不同的组件复制CSS。
 98     new OptimizeCSSPlugin({
 99       cssProcessorOptions: config.build.productionSourceMap ? {
100         safe: true,
101         map: {
102           inline: false
103         }
104       } : {
105         safe: true
106       }
107     }),
108     // generate dist index.html with correct asset hash for caching.
109     // you can customize output by editing /index.html
110     // see https://github.com/ampedandwired/html-webpack-plugin
111     new HtmlWebpackPlugin({
112       filename: process.env.NODE_ENV === 'testing' ?
113         'index.html' : config.build.index,
114       template: 'index.html',
115       favicon: path.resolve(__dirname, '../static/images/favicon.ico'),
116       inject: true,
117       minify: {
118         removeComments: true,
119         collapseWhitespace: true,
120         removeAttributeQuotes: true
121         // more options:
122         // https://github.com/kangax/html-minifier#options-quick-reference
123       },
124       // necessary to consistently work with multiple chunks via CommonsChunkPlugin
125       chunksSortMode: 'manual',
126       dll: (function () {
127         let max = 2
128         let res = []
129         for (let i = 0; i < max; i++) {
130           const dllName = require(path.resolve(__dirname, `../dllManifest/xuAdmin${i}-manifest.json`)).name.split('_')
131           res.push(`./static/dll/${dllName[0]}.${dllName[1]}.dll.js`)
132         }
133         return res
134       })()
135     }),
136     // keep module.id stable when vendor modules does not change
137     new webpack.HashedModuleIdsPlugin(),
138     // enable scope hoisting
139     new webpack.optimize.ModuleConcatenationPlugin(),
140     // split vendor js into its own file
141 
142     // extract webpack runtime and module manifest to its own file in order to
143     // prevent vendor hash from being updated whenever app bundle is updated
144 
145     // This instance extracts shared chunks from code splitted chunks and bundles them
146     // in a separate chunk, similar to the vendor chunk
147     // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
148 
149 
150     // 复制自定义静态资产
151     new CopyWebpackPlugin([{
152       from: path.resolve(__dirname, '../static'),
153       to: config.build.assetsSubDirectory,
154       ignore: ['.*']
155     }]),
156   ]
157 })
158 
159 
160 //压缩
161 if (config.build.productionGzip) {
162   const CompressionWebpackPlugin = require('compression-webpack-plugin')
163 
164   webpackConfig.plugins.push(
165     new CompressionWebpackPlugin({
166       asset: '[path].gz[query]', // 目标资源名称 [path]会被替换成原始资源的路径 [query]会被替换成查询字符串
167       algorithm: 'gzip', // 按照zlib的算法
168       // 所有匹配该正则的资源都会被处理 默认值是全部资源
169       test: new RegExp(
170         '\\.(' +
171         config.build.productionGzipExtensions.join('|') +
172         ')$'
173       ),
174       threshold: 10240, // 只有大小大于该值得资源会被处理,单位是bytes
175       minRatio: 0.8 // 压缩率小于这个值得资源才会被处理 默认值是 0.8
176     })
177   )
178 }
179 
180 //打包文件分析工具
181 if (config.build.bundleAnalyzerReport) {
182   const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
183   webpackConfig.plugins.push(new BundleAnalyzerPlugin())
184 }
185 
186 //导出
187 module.exports = webpackConfig