Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack 打包优化 #28

Open
yeojongki opened this issue Mar 15, 2020 · 0 comments
Open

Webpack 打包优化 #28

yeojongki opened this issue Mar 15, 2020 · 0 comments

Comments

@yeojongki
Copy link
Owner

1. 配置 exclude / include

这里以 loader 为例,在 loader 解析时,指定或者排除某个目录

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/, // 不解析 node_modules
        include: path.resolve('src'), // 只解析 src 目录下的文件,两者写其一即可
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react']
          }
        }
      }
    ]
  }
}

2. noParse

防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中不应该含有 import, require, define 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。

module.exports = {
  //...
  module: {
    // 使用正则表达式
	noParse: /jquery|lodash/
    // 使用函数,从 Webpack 3.0.0 开始支持
    noParse: (content)=> {
      // content 代表一个模块的文件路径
      // 返回 true or false
      return /jquery|lodash/.test(content);
    }
    noParse: (content) => /jquery|lodash/.test(content)
  }
};

3. IgnorePlugin

阻止生成用于导入的模块,或阻止与正则表达式或过滤器函数匹配的调用

moment 2.18 会将所有本地化内容和核心功能一起打包(见该 GitHub issue)。你可使用 IgnorePlugin 在打包时忽略本地化内容

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)

4. DLLPlugin 和 DLLReferencePlugin

DLLPluginDLLReferencePlugin 用某种方法实现了拆分 bundles,提前将基本不会变的 bundle 打包好,下一次打包的时候,不需要重复打包

// webpack.dll.config.js
const webpack = require('webpack')

module.exports = {
  entry: {
    react: [
      'react',
      'react-dom'
      //其他库
    ]
  },
  output: {
    path: './build',
    filename: '[name].dll.js',
    libraryTarget: 'var',
    library: 'dll_[name]_[hash]'
  },
  plugins: [
    new webpack.DllPlugin({
      path: './build/react.manifest.json',
      // 注意:与 output.library 保持 name 的一致性。
      name: 'dll_[name]_[hash]'
    })
  ]
}
// webpack.config.js
const webpack = require('webpack')

module.exports = {
  // ...
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./build/react.manifest.json')
    })
  ]
}

最后在 html 中插入 react.dll.js

另外可以通过 html-webpack-tags-plugin 自动注入 DLLhtml

5. Happypack

HappyPack 通过并行转换文件来加快初始Webpack的构建速度

6. optimization

const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        cache: true,
        parallel: true,
        sourceMap: true,
        terserOptions: {
          // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
        }
      })
    ]
  },
  // 默认配置
  splitChunks: {
    chunks: 'async', // all 全部(推荐), async 分割异步块, initial
    minSize: 30000, // 抽取出来的文件在压缩前的最小大小
    maxSize: 0, // 抽取出来的文件在压缩前的最大大小, 默认为 0,表示不限制最大大小
    minChunks: 1, // 最小公用模块次数
    maxAsyncRequests: 5, // 按需加载时并行请求的最大数量
    maxInitialRequests: 3, // 入口点的最大并行请求数
    automaticNameDelimiter: '~', // 文件名称分隔符号
    // 文件名,值可以是 boolean | function (module, chunks, cacheGroupKey) | string
    name: true,
    // 缓存策略,默认设置了分割 node_modules 和公用模块
    // 会继承splitChunks的配置,但是test、priorty和reuseExistingChunk只能用于配置缓存组
    cacheGroups: {
      vendors: {
        test: /[\\/]node_modules[\\/]/,
        priority: -10 // 优先级
      },
      default: {
        minChunks: 2,
        priority: -20,
        reuseExistingChunk: true // 是否复用存在的 chunk
      }
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant