高级优化7.Code Split 代码分割

为什么

打包代码时会将所有 js 文件打包到一个文件中,体积太大了。我们如果只要渲染首页,就应该只加载首页的 js 文件,其他文件不应该加载。所以我们需要将打包生成的文件进行代码分割,生成多个 js 文件,渲染哪个页面就只加载某个 js 文件,这样加载的资源就少,速度就更快。

是什么

代码分割(Code Split)主要做了两件事:

  1. 分割文件:将打包生成的文件进行分割,生成多个 js 文件。

  1. 按需加载:需要哪个文件就加载哪个文件。

  1. 多入口

案例:

  • app.js

console.log("hello app");
  • main.js

console.log("hello main");

配置:

constHtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
   // 多入口
  entry: {
    main: "./src/main.js",
    app: "./src/app.js",
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    // [name]是webpack命名规则,使用chunk的name作为输出的文件名。// 什么是chunk?打包的资源就是chunk,输出出去叫bundle。// chunk的name是啥呢? 比如: entry中xxx: "./src/xxx.js", name就是xxx。注意是前面的xxx,和文件名无关。// 为什么需要这样命名呢?如果还是之前写法main.js,那么打包生成两个js文件都会叫做main.js会发生覆盖。(实际上会直接报错的)
    filename: "js/[name].js",
    clear: true,
  },
  plugins: [
    newHtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
  mode: "production",
};

运行指令

npx webpack

此时在 dist 目录我们能看到输出了两个 js 文件。

编辑

打包后的 index.html 自动引入了两个打包好的 js 文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Code Split</title>
    <script defer="defer" src="app.js"></script>
    <script defer="defer" src="main.js"></script>
  </head>
  <body>
    <h1>hello webpack</h1>
  </body>
</html>

总结:配置了几个入口,至少输出几个 js 文件。

  1. 多入口提取公共模块

如果多入口文件中都引用了同一份代码,我们不希望这份代码被打包到两个文件中,导致代码重复,体积更大。我们需要提取多入口的重复代码,只打包生成一个 js 文件,其他文件引用它就好。

实例:

  1. 修改文件

  • app.js

import { sum } from "./math";

console.log("hello app");
console.log(sum(1, 2, 3, 4));
  • main.js

import { sum } from "./math";

console.log("hello main");
console.log(sum(1, 2, 3, 4, 5));
  • math.js

export const sum = (...args) => {
  return args.reduce((p, c) => p + c, 0);
};

修改配置文件

// webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  // 多入口
  entry: {
    main: "./src/main.js",
    app: "./src/app.js",
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "js/[name].js",
    clean: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
  mode: "production",
  // 压缩代码
  optimization: {
    // 代码分割配置
    splitChunks: {
      chunks: "all", // 对所有模块都进行分割
      // 修改配置
      cacheGroups: {
        // 组,哪些模块要打包到一个组
        default: {
          // 其他没有写的配置会使用上面的默认值
          minSize: 0, // 我们定义的文件体积太小了,所以要改打包的最小文件体积
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};

运行指令: npx webpack

3. 按需加载,动态导入

一个点击执行的操作,只有点击的时候才会执行,如果不点击,就不想让它加载,只有点击的时候才加载。想要实现按需加载,动态导入模块。还需要额外配置:

  1. 修改文件

  • main.js

console.log("hello main");

document.getElementById("btn").onclick = function () {
  // 动态导入 --> 实现按需加载
  // 即使只被引用了一次,也会代码分割
  import("./math.js").then(({ sum }) => {
    alert(sum(1, 2, 3, 4, 5));
  });
};
  • app.js

console.log("hello app");
  • public/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Code Split</title>
  </head>
  <body>
    <h1>hello webpack</h1>
    <button id="btn">计算</button>
  </body>
</html>

运行指令:npx webpack

一旦通过 import 动态导入语法导入模块,模块就被代码分割,同时也能按需加载了。

4.单入口

开发时我们可能是单页面应用(SPA),只有一个入口(单入口)。那么我们需要这样配置:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  // 单入口
  entry: "./src/main.js",
  // 多入口
  // entry: {
  //   main: "./src/main.js",
  //   app: "./src/app.js",
  // },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "js/[name].js",
    clean: true,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
  mode: "production",
  optimization: {
    // 代码分割配置
    splitChunks: {
      chunks: "all"
  },
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值