從零搭建webpack4+react+typescript+eslint腳手架(三)

處理靜態資源

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'
      }
    }
  }
}

壓縮代碼(2019/9/18更新)

經過使用打包分析工具,咱們會發現打出來的包都很大,遠不能知足生產環境的體積要求,所以還須要對代碼進行壓縮。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
    })
  ]
}

運行打包命令,查看打包好的文件,能夠看到代碼都被壓縮好了。

使用terser

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

相關文章
相關標籤/搜索