webpack》》code split 代码分割

Code split 代码分割

默认情况下,一些第三方库以及一些首页用不到的业务代码很可能都打到相同的bundle中在第一时间加载,那将使首页加载的速度变慢
代码分割的主要目的是将代码分割到不同的bundle中,这样就可以对bundle进行选择性的并行加载或者按需加载
默认情况下,打包代码时会将所有js文件打包到一个文件中,体检太大了。如果我们只渲染首页,就应该只加载首页的js文件,其他文件不应该加载
所以我们要将打包生成的文件进行代码分割,生成多个js文件。渲染哪个页面只加载某个js文件。这样加载的资源就少,速度就更快。

代码分割(Code Split) 主要做了两件事:
1、分割文件: 将打包生成的文件进行分割,生成多个js文件
2、按需加载:需要哪个文件就加载哪个文件

多入口对应多出口 配置了几个入口,至少输出几个 js 文件。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
  //单入口
  //entry: './src/index.js',
  多入口
  entry:{
    app:'./src/app.js',
    index:'./src/index.js'
  }
  output: {
    path: path.resolve(__dirname, 'build'),
    ////当entry有多个入口文件时,用[]可以输出多个文件 filename: '[name].js',
    // 入口文件打包输出的文件名
    filename: 'static/js/[name].js',
    // 给打包输出的其他文件命名
    chunkFilename:"static/js/[name].chunk.js",
    //自动清空上次打包的内容
    // 原理:在打包前,将path整个目录清空,再进行打包
    clean: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'})
  ]
}

》》》 提取重复代码
在这里插入图片描述

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

  /*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
  */
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // 单入口
  // entry: './src/js/index.js',
  entry: {
    index: './src/js/index.js',
    test: './src/js/test.js'
  },
  output: {    
     // 入口文件打包输出的文件名
    filename: 'static/js/[name].[contenthash:10].js',
    // 给打包输出的其他文件命名
    chunkFilename:"static/js/[name].[contenthash:10].chunk.js",
    path: resolve(__dirname, 'build')   
    
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  /*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
  */
  optimization: {
    splitChunks: {
      chunks: 'all'
        //其他配置 采用默认配置
    }
  },
  mode: 'production'
};

》》optimization 的默认配置

optimization: {
    // 代码分割配置
    splitChunks: {
      chunks: "all", // 对所有模块都进行分割
      // 以下是默认值
      // minSize: 20000, // 分割代码最小的大小
      // minRemainingSize: 0, // 类似于minSize,最后确保提取的文件大小不能为0
      // minChunks: 1, // 至少被引用的次数,满足条件才会代码分割
      // maxAsyncRequests: 30, // 按需加载时并行加载的文件的最大数量
      // maxInitialRequests: 30, // 入口js文件最大并行请求数量
      // enforceSizeThreshold: 50000, // 超过50kb一定会单独打包(此时会忽略minRemainingSize、maxAsyncRequests、maxInitialRequests)
      // cacheGroups: { // 组,哪些模块要打包到一个组
      //   defaultVendors: { // 组名
      //     test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块
      //     priority: -10, // 权重(越大越高)
      //     reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
      //   },
      //   default: { // 其他没有写的配置会使用上面的默认值
      //     minChunks: 2, // 这里的minChunks权重更大
      //     priority: -20,
      //     reuseExistingChunk: true,
      //   },
      // },
      // 修改配置
      cacheGroups: {
        // 组,哪些模块要打包到一个组
        // defaultVendors: { // 组名
        //   test: /[\\/]node_modules[\\/]/, // 需要打包到一起的模块
        //   priority: -10, // 权重(越大越高)
        //   reuseExistingChunk: true, // 如果当前 chunk 包含已从主 bundle 中拆分出的模块,则它将被重用,而不是生成新的模块
        // },
        default: {
          // 其他没有写的配置会使用上面的默认值
          minSize: 0, // 我们定义的文件体积太小了,所以要改打包的最小文件体积
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
}

动态导入 - 按需加载

// 案例:点击按钮时加载一个重型模块
document.getElementById('btn').addEventListener('click', async () => {
  // 使用魔法注释指定 chunk 名称
  // import 动态导入:会将动态导入的文件代码 分割(拆分成单独模块),在需要使用的时候自动加载
  const { zen} = await import(
    /* webpackChunkName: "chart" */ 
    './xxx.js'
  );
  zen();
  //或者,  eslint 不能识别动态导入需要,需要额外追加配置 import 
  import(/*webpackChunkName:"zen"*/,'./xxjs').then({zen})=>{}).catch((err)=>{})
});

// React 组件懒加载
const HeavyComponent = React.lazy(() => 
  import(/* webpackChunkName: "heavy-comp" */ './HeavyComponent')
);

抽离代码 splitChunks

const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // 单入口
  entry: './src/js/index.js',  
  output: {    
     // 入口文件打包输出的文件名
    filename: 'static/js/[name].[contenthash:10].js',
    // 给打包输出的其他文件命名
    chunkFilename:"static/js/[name].[contenthash:10].chunk.js",
    path: resolve(__dirname, 'build')   
    
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
      minify: {
        collapseWhitespace: true,
        removeComments: true
      }
    })
  ],
  /*
    1. 可以将node_modules中代码单独打包一个chunk最终输出
    2. 自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
  */
  optimization: {
    splitChunks: {
      chunks: 'all',
      //其他配置 采用默认配置
    }
  },
  mode: 'production'
};

webpack 5 资源的统一命令

output: {    
     // 入口文件打包输出的文件名
    filename: 'static/js/[name].[contenthash:10].js',
    // 给打包输出的其他文件命名
    chunkFilename:"static/js/[name].[contenthash:10].chunk.js",
    path: resolve(__dirname, 'build'),  
    // 图片、字体等通过 type:asset 处理的资源的命名方式 
    assertModuleFileName:"static/media/[hash:10][ext][query]"
  },

{
	test: /\.(png|jpg|jpeg|gif|svg|webp|ico)$/, // 匹配所有的图片文件
	type: "asset", // 图片资源类型
	// 因为  output 配置了  assertModuleFileName  下面可以不要了
	// 图片资源生成配置 
	//generator: {
	// 输出文件名
	//filename: "images/[name].[ext]",
    //}
}

preload prefetch 预加载

preload

# Preload:  告诉浏览器立即加载资源
# Prefetch: 告诉浏览器在空闲时才开始加载资源

在这里插入图片描述

eslint 配置

npm i eslint-plugin-import -D

// .eslintrc.js
module.exports = {
  // 继承 Eslint 规则
  extends: ["eslint:recommended"],
  env: {
    node: true, // 启用node中全局变量
    browser: true, // 启用浏览器中全局变量
  },
  plugins: ["import"], // 解决动态导入import语法报错问题 --> 实际使用eslint-plugin-import的规则解决的
  parserOptions: {
    ecmaVersion: 6,
    sourceType: "module",
  },
  rules: {
    "no-var": 2, // 不能使用 var 定义变量    
  },
  plugins:["import"]
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值