webpack模块分割-社区精选|了解了这些概念,对webpack有了新的认识

2023-08-29 0 9,621 百度已收录

今天小编给大家带来一篇社区作者limingcan的文章。 让我们学习一下使用webpack涉及到的几个概念,以便我们更好的理解webpack编译过程。

前言

随着vite的诞生,webpack似乎慢慢被你抛弃了。 前段时间我也用vue@3.x + vite@4.x开发了一个后台管理系统,体验了一下,着实被vite快速的启动速度震惊了。

不过webpack虽然诞生已经很久了,但也经过了市场的一些考验,而且插件丰富,功能丰富,一些小项目也使用了它。 目前是比vite更稳定的打包工具。

出于以下原因:

所以,想来想去,我决定开一个webpack专栏,和大家一起学习如何配置webpack(虽然专栏有点晚了)。

专栏将带您一步步学习webpack,从更多的实际例子开始,让您更好地理解webpack,最终自己准备一个完整的webpack脚手架。 当我们学会自己配置webpack后,我们可以根据自己的不同需求高度定制自己的脚手架,还是很实用的。

本文的主要核心就是和大家一起了解一下使用webpack所涉及到的概念,以便我们更好的理解webpack的编译过程。

什么是网页包

它是一个打包工具:

webpack.config.js

v4.0.0之后,webpack有了一个开箱即用的功能,就是我们安装了webpack和webpack-cli这两个依赖之后,就可以直接打包,不需要任何配置文件。

这是因为:

但我们通常会在项目根目录中创建一个名为 webpack.config.js 的新配置文件。 这可以指导webpack如何处理我们项目中的文件、资源等; 通过更加高度定制的配置来满足我们项目的需求。

我们看一下这个配置文件的大致框架是什么样的,心里有一个印象:

// webpack.config.js
module.exports = {
    // 入口
    entry: {},

    // 打包输出
    output: {},

    // 配置模块如何解析
    resolve: {},

    // 配置各种loader
    module: {},

    // 配置插件
    plugins: [],

    // 优化(可以进行代码分割)
    optimization: {},

    // webpack-dev-server 开发时的配置,一般用于development模式
    devServer: {}
};

其实webapck也支持很多配置项,不过这些是我们平时使用的,其他的配置项可以在文档中找到。

注意

webpack配置文件,里面的代码你想玩什么就玩什么,配置文件的名字不一定非得是webpack.config.js,只要最终输出的是一个webpack配置对象即可:

// myconfig.js

// 各种逻辑代码
...
...

// 保证最后导出一个`webpack`配置的对象就可以
module.exports = {
    // 各种webpack配置
    entry: {},
    output: {},
    ....
}

"build""webpack --config myconfig.js"

优化

所有配置都写在一个文件中,不利于我们维护和开发; 而我们开发项目时,会存在多种环境(本地开发环境、测试环境、生产环境)webpack模块分割,所以我们通常会有针对不同环境的配置文件。 所有环境的通用配置文件。

我们通常会将“通用配置文件”与“不同环境的配置文件”进行合并,最后通过webpack运行合并后的配置文件。

配置文件通常有:

后续文章将教您如何进行这些配置

入口

它指的是webpack开始解析并构建依赖图的起点。 我们通常使用 {key: value} 对象来配置条目,例如:

module.exports = {
    entry: {
        index: './src/index.js',
        share: './src/share.js',
    },
}

这意味着:

输出

它很容易理解,它可以设置webpack打包的编译文件的名称,以及应该输出的位置。

需要注意的是,即使我们设置了多个entry条目,也只能指定一种输出配置。

模块

我们导入或者需要的资源文件,或者说我们项目中的每一个文件,都可以看成是一个独立的模块。 因此,它可以是任何类型的资源,例如js文件、css文件或图片。 所以我们在开发中经常会听到以下这句话:

模块的组合会生成一个Chunk。 Chunk是一个非常重要的概念,后面会详细讨论。

参考文章:模块 (#what-is-a-webpack-module)

装载机

通过上面我们知道,项目中的每个文件都可以看成是一个模块,而由于我们的文件类型多种多样,所以我们需要有一个东西可以把这个模块解析成webpack可以识别的有效模块,并将其添加到依赖图,这个东西就是Loader。

webpack还好心地为我们提供了一个模块配置项,专门用来配置不同的loader,从而解析不同的文件类型(模块)。 这是因为webpack默认只能解析js和json文件,所以如果我们要解析不同类型的文件(模块),就需要安装相应的loader:

// webpack.config.js
module.exports = {
    ...,
    modules: {
        rules: [
            // 解析.txt文件,使用raw-loader
            { test: /.txt$/, use: 'raw-loader' },
        ],
    }
}


加载器有两个属性:

在webpack中,还有哪些其他加载器可以在这里看到()

webpack模块分割-社区精选|了解了这些概念,对webpack有了新的认识

插件

Loader用于转换模块,Plugin用于打包编译时增强webpack的功能。 所以它通常具有打包优化、资源管理、环境变量注入等功能。

因此,webpack还贴心地为我们提供了插件配置项。 我们想要完善哪些功能都可以在插件中进行配置。 比如我们项目中直接定义一些全局变量:

// webpack.config.js
module.exports = {
    ...,
    plugins: [
         new webpack.DefinePlugin({
            AUTHOR_NAME: JSON.stringify('Lee'),
        })
    ]
}

// index.js
console.log(AUTHOR_NAME); // Lee


webpack中还有哪些插件可以看这里()

依赖图(依赖图)

当我们有一个文件依赖于另一个文件时,webpack 会将该文件视为直接“依赖项”。

举个简单的例子,假设我们有三个文件,它们的关系如下:

// main.js
import './index.js';

// index.js
import 'plugin.js'
console.log('I am from index.js');

// plugin.js
console.log('I am plugin.js');


我们来剖析一下:

main.js、index.js、plugin.js相当于三个模块;

然后main.js引入了index.js,index.js又引入了plugin.js;

因此,这三个文件都具有相互引用的关系;

这时就生成了这样一张有引用关系的图:main.js→index.js→plugin.js

总结:

webpack将从入口开始,并将其作为依赖图的起点; 然后对entry中的内部导入进行分析处理,不断递归查询类似上面例子的依赖关系。 这个过程最终会生成一个具有依赖关系的图。 这个图是一个“依赖图”。

webpack 将遵循这个依赖图进行进一步的操作。

我们在查阅webpack中文文档的时候,经常会听到Chunk这个词,这个词还没有翻译成英文。 这是因为Chunk是webpack打包过程中形成的逻辑概念,其含义需要结合上下文来理解。

webpack模块分割-社区精选|了解了这些概念,对webpack有了新的认识

Chunk是webpack中一个比较重要的概念。 如果我们理解了它,我们就会很好地理解webpack打包和代码分割的整个过程。

解释

在webpack打包过程中,一个或者一组模块(我们上面提到的webpack中的任何一个文件都可以看作是一个模块)会被组合成一个整体,那么这个整体就可以看作是一个Chunk。 一般来说,webpack在打包过程中,会产生若干个Chunk,最终会输出若干个js文件。

我们以learn-01为例,它包含最简单的配置和最简单的代码,以便更好地理解Chunk是什么。

我们有三个js文件:

文件代码和webpack配置如下:

// webpack.config.js
module.exports = {
    entry: {
        index: './src/index.js'
    },
    output: {
        filename: '[name]-bundle.js'
    }
}

// index.js
import './vendors';
import(/* webpackChunkName: "async" */ './async');
console.log('I am from index.js');

// async.js
console.log('I am from async.js');

// vendors.js
console.log('I am from vendors.js');

看到这里,我们首先可以猜测一下打包了多少个文件。 如果你猜对了,说明你对Chunk有了一定的了解。

分析

我们先来分析一下打包后的文件和结构:

dist
├── async-bundle.js
└── index-bundle.js

总共输出两个js文件。

通过上述,我们知道:

我们接着分析:

好了,相信到这里,大家应该对Chunk有了一个大概的印象了,我们再回顾一下整个过程。

编译webpack时,通过我们的配置:

首先会找到Enrty,如果有多个条目webpack模块分割,则会与该条目组成一个Chunk组(示例中为Chunk[index])

然后分析这种Chunk组,与入口js以及该入口的所有相关依赖模块组成一个chunk(例子中的chunk[initial])

如果有异步引入的模块,该模块会形成一个Chunk(示例中为chunk[no-initial])

最后打包输出 chunk[initial] (index-bundle.js), chunk[no-initial] (async-bundle.js)

上面的例子中,chunk和module的关系如下:

形式

通过上面的分析,我们可以知道Chunk有两种类型:

如何形成一个 chunk

通过前面的讲解和分析,希望大家以后使用webpack的时候,能够在脑海里有一个大概的Chunk形成的过程,这对于我们使用代码分割是非常有帮助的。

参考文章:揭示内部原理()

Bundle是指所有通过webpack打包的产品。

如果我们的输出配置打包后的输出文件目录是dist,那么我们的Bundle就是dist文件夹上面的所有产品。

一般来说有几个Chunk,就会打包多少个js的bundle文件。

包装工艺

分析

为了让大家更好的理解上面分析的概念,我们来探究一下webpack的打包流程,看看上面的概念是在什么过程中体现的。

我们在终端运行webpack后,会经历以下过程:

读取我们指定的配置文件(webpack.config.js)

从入口入口开始,分析我们的Module(模块),递归我们整个项目模块之间的依赖关系

加载对应的Loader,将这个Module(模块)解析成webpack可以识别的有效模块,并将它们添加到依赖图(Dependency graph)中

编译过程会触发多次风暴并执行配置好的Plugin(插件)

将剖析的模块分组为块

webpack模块分割-社区精选|了解了这些概念,对webpack有了新的认识

根据配置文件(输出),输出最终的Bundle

上述过程可以看作三个阶段:

可以概括为右图:

webpack实际的打包过程其实要复杂很多,这里为了更好理解,简化一下

去体验

让我们从实际出发,通过learn-02的案例,用实际代码来体验和理解webpack打包流程以及涉及到的概念。

我们看一下learn-02项目结构:

learn-02
├── index.html
├── package-lock.json
├── package.json
├── project.config.js
└── src
    ├── assets
    │   └── style.less
    ├── index.js
    ├── plugin
    │   ├── common.js
    │   ├── index-vendors.js
    │   └── share-vendors.js
    └── share.js

我们来介绍一下对应的文件:

以下项目中的相关代码:

我们看到project.config.js的配置后,就可以猜测打包后会输出多少个文件了。

好啦,现在我们开始剖析:

1.当我们在终端运行 npm run build 时,webpack会读取我们指定的文件project.config.js

2、从入门开始,分析我们的模块。 我们的entry有两个index和share,所以此时会生成两个Chunk组:Chunk[index],Chunk[share],并且我们的模块对应的依赖会被递归。

3、index.js引入了style.less,所以它会加载对应的Loader,解析成webpack可以识别的有效模块,并添加到依赖图中。 此时会生成两个依赖图:

4.然后对该模块进行分组:

5、发现我们的配置中,commonjs也是通过代码分段的方式独立分离出来的,所以独立形成了一个chunk[initial-common]

6. 到目前为止,webpack 已经分离了三个块:

7.根据输出,最终输出Bundle

再次强调,实际的封装过程肯定要复杂得多

终于

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 webpack webpack模块分割-社区精选|了解了这些概念,对webpack有了新的认识 https://www.wkzy.net/game/174192.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务