代码分离能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle,以及控制资源加载优先级,可以缩短页面加载时间。

2.1 抽离重复代码

SplitChunksPlugin 插件开箱即用,可以将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。

webpack 将根据以下条件自动拆分 chunks:

  • 新的 chunk 可以被共享,或者模块来自于 node_modules 文件夹;
  • 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积);
  • 当按需加载 chunks 时,并行请求的最大数量小于或等于 30;
  • 当加载初始化页面时,并发请求的最大数量小于或等于 30;

通过 splitChunks 把 react 等公共库抽离出来,不重复引入占用体积。

注意:切记不要为 cacheGroups 定义固定的 name,因为 cacheGroups.name 指定字符串或始终返回相同字符串的函数时,会将所有常见模块和 vendor 合并为一个 chunk。这会导致更大的初始下载量并减慢页面加载速度。

webpack.prod.js 配置方式如下:

  1. module.exports = {
  2. splitChunks: {
  3. // include all types of chunks
  4. chunks: 'all',
  5. // 重复打包问题
  6. cacheGroups:{
  7. vendors:{ // node_modules里的代码
  8. test: /[\\/]node_modules[\\/]/,
  9. chunks: "all",
  10. // name: 'vendors', 一定不要定义固定的name
  11. priority: 10, // 优先级
  12. enforce: true
  13. }
  14. }
  15. },
  16. }

将公共的模块单独打包,不再重复引入,效果如下:

image.png

2.2 CSS 文件分离

MiniCssExtractPlugin 插件将 CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。

安装:

  1. npm i -D mini-css-extract-plugin

webpack.common.js 配置方式如下:

  1. const MiniCssExtractPlugin = require("mini-css-extract-plugin");
  2. const ctx = {
  3. isEnvDevelopment: process.env.NODE_ENV === 'development',
  4. isEnvProduction: process.env.NODE_ENV === 'production',
  5. }
  6. const {
  7. isEnvDevelopment,
  8. isEnvProduction
  9. } = ctx
  10. module.exports = {
  11. plugins: [new MiniCssExtractPlugin()],
  12. module: {
  13. rules: [
  14. {
  15. test: /\.module\.(scss|sass)$/,
  16. include: paths.appSrc,
  17. use: [
  18. 'style-loader',
  19. isEnvProduction && MiniCssExtractPlugin.loader, // 仅生产环境
  20. {
  21. loader: 'css-loader',
  22. options: {
  23. modules: true,
  24. importLoaders: 2,
  25. },
  26. },
  27. {
  28. loader: 'postcss-loader',
  29. options: {
  30. postcssOptions: {
  31. plugins: [
  32. [
  33. 'postcss-preset-env',
  34. ],
  35. ],
  36. },
  37. },
  38. },
  39. {
  40. loader: 'thread-loader',
  41. options: {
  42. workerParallelJobs: 2
  43. }
  44. },
  45. 'sass-loader',
  46. ].filter(Boolean),
  47. },
  48. ]
  49. },
  50. };

注意:MiniCssExtractPlugin.loader 要放在 style-loader 后面。