js的打包基本处理完了,还有图片、音频等静态资源须要处理。javascript
依然先装依赖:css
$ npm i -D url-loader file-loader $ npm i -D @svgr/webpack # 顺带支持一下导入svg图片
增长webpack配置:html
// webpack.base.js { test: /\.svg$/, use: ['@svgr/webpack'] }, { test: /\.(jpg|jpeg|bmp|png|webp|gif)$/, loader: 'url-loader', options: { limit: 8 * 1024, // 小于这个大小的图片,会自动base64编码后插入到代码中 name: 'img/[name].[hash:8].[ext]', outputPath: config.assetsDirectory, publicPath: config.assetsRoot } }, // 下面这个配置必须放在最后 { exclude: [/\.(js|mjs|ts|tsx|less|css|jsx)$/, /\.html$/, /\.json$/], loader: 'file-loader', options: { name: 'media/[path][name].[hash:8].[ext]', outputPath: config.assetsDirectory, publicPath: config.assetsRoot } }
tips: 生产环境须要合理使用缓存,须要拷贝一份一样的配置在webpack.prod.js
中,并将name中的hash
改成contenthash
接下来咱们要把public
目录里除了index.html
之外的文件都拷贝一份到打包目录中:java
安装依赖:node
$ npm i -D copy-webpack-plugin
增长配置:react
// webpack.base.js const CopyWebpackPlugin = require('copy-webpack-plugin'); plugins: [ // ...other plugins new CopyWebpackPlugin([ { from: 'public', ignore: ['index.html'] } ]) ]
有些模块是公共的,若是不把他拆分出来,那么他会在每个被引入的模块中出现,咱们须要优化与此相关的配置。webpack
// webpack.prod.js entry: { app: './src/index.tsx', vendor: ['react', 'react-dom'] // 不变的代码分包 }, optimization: { splitChunks: { chunks: 'all', minChunks: 2, maxInitialRequests: 5, cacheGroups: { // 提取公共模块 commons: { chunks: 'all', test: /[\\/]node_modules[\\/]/, minChunks: 2, maxInitialRequests: 5, minSize: 0, name: 'common' } } } }
经过使用打包分析工具,咱们会发现打出来的包都很大,远不能知足生产环境的体积要求,所以还须要对代码进行压缩。web
安装依赖:typescript
$ npm i -D uglifyjs-webpack-plugin mini-css-extract-plugin compression-webpack-plugin
增长和修改配置:npm
// webpack.prod.js const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CompressionWebpackPlugin = require('compression-webpack-plugin'); { test: /\.(less|css)$/, use: [ MiniCssExtractPlugin.loader, // 注意书写的顺序 { loader: 'css-loader', }, 'postcss-loader', { loader: 'less-loader', options: { javascriptEnabled: true, } } ] }, // ...configs plugins: [ new HtmlWebpackPlugin({ template: config.indexPath, minify: { removeComments: true, collapseWhitespace: true, removeRedundantAttributes: true, useShortDoctype: true, removeOptionalTags: false, removeEmptyAttributes: true, removeStyleLinkTypeAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true, removeAttributeQuotes: true, removeCommentsFromCDATA: true, keepClosingSlash: true, minifyJS: true, minifyCSS: true, minifyURLs: true, } }), new MiniCssExtractPlugin({ filename: 'css/[name].[contenthash:8].css' // chunkFilename: '[name].[contenthash:8].chunk.css' }), // gzip压缩 new CompressionWebpackPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'), threshold: 10240, // 大于这个大小的文件才会被压缩 minRatio: 0.8 }), ], optimization: { minimizer: [ new UglifyjsWebpackPlugin({ sourceMap: config.productionJsSourceMap }) ] }
运行打包命令,查看打包好的文件,能够看到代码都被压缩好了。
因为uglify-es
已经中止维护,因此改用目前比较流行的terser
来压缩js代码。咱们仅需作几处简单的修改。
首先安装依赖:
$ npm i -D terser-webpack-plugin
而后改写webpack.prod.js
便可:
// const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin'); optimization: { minimizer: [ // new UglifyjsWebpackPlugin({ // sourceMap: config.productionJsSourceMap // }) new TerserPlugin({ sourceMap: config.productionJsSourceMap }) ] }