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 }) ] }