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进阶系列】seal封装生成文件核心流程 #101

Open
amandakelake opened this issue Feb 4, 2020 · 2 comments
Open

【webpack进阶系列】seal封装生成文件核心流程 #101

amandakelake opened this issue Feb 4, 2020 · 2 comments

Comments

@amandakelake
Copy link
Owner

amandakelake commented Feb 4, 2020

一、前言

【webpack进阶系列】构建module核心流程
在前面make钩子,已经把所有的modules编译完成并存放在compilation.modules中,数据结构大概如下

compilation = {
    // ...
    modules: [{
        // ...
        dependencies: [{
            // ...
            module: {
                // ...
                dependencies: [{
                    // ...
                    module: {
                        // ... 不断递归
                    }
                }]
            }
        }, {}]
    }, {}]
};

根据以上compilation.modules的数据结构,webpack已经有能力找到所有的依赖,那么接下来就是如何把这些modules进行封装

二、总览

seal的任务是把上面的modules生成chunk,生成最终源码存放在compilation.assets属性上(期间有各种性能优化)

在webpack中chunk的概念有两个
* 配置在entry的模块,也就是入口文件
* 动态引入的模块(require/import进来的)

每个chunk其实就是找到以上两种概念中的一个模块,entry module和动态module生成的chunk的区别在于后面调用的模板不一样

这里模板的概念,是指根据chunk调用模板的render方法渲染成源码,entry module选择mainTemplate,动态module选择chunkTemplate

三、compilation.seal

seal的前面很大一部分代码都是调用性能优化相关的内置插件,对模块做最后的优化,搜一下optimize这个词就知道了
28226861-520E-45A7-A3A4-F5E6A50EE3C8

这里有个地方注意一下,优化类的插件全部是同步钩子(做优化当然是一步步像个水管一样流动,异步的话互相穿插很容易混淆插件之间的入口代码)

优化完成后根据entry创建第一类chunk,有多少个entry module就创建多少个chunk,然后根据chunk递归处理是否有异步module,创建二类chunk,然后调用createChunkAssets根据不同的模板来生成源码对象,最后再缓存和生成sourceMap,最后存放到compilation.assets
EBCDAC7F-6001-4140-A1EF-DC53906B91AA

关于template,compilation在实例化的时候,就已经实例化了3个对象
* mainTemplate
* chunkTemplate
* moduleTemplates
三个对象的作用分别如图
ECD63121-B214-4621-8184-CD376E1F41EC
4ZUS64uSa5knwh3-zLwQW-yg_KVM_wRS7m7qOfo5US6WaPbQIZLQe624-jfLKDYJoPrsqdPnde0iswdVjaZwI9De8hSelZkbaogdc5WcJnbZXU21P_wTmDfzxYsMlMJ9BlIu7mT0tS8

seal后存放在compilation.assets里最后的产物,每个entry模块对应一个key对象,里面的动态chunk存放在children数组中
4E7C1187-301F-4E26-A61C-14D30D3B000B

四、输出文件

seal完成后,一路回到compiler.run -> this.compile(onCompiled) -> this.emitAssets,也就是调用compiler.emitAssets,按照output的配置,通过outputFileSystem.writeFile把结果输出到文件中,至此,webpack整个打包流程结束

@narol1024
Copy link

我调试之后发现,Webpack5 compilation.modules的数据结构是这样的:

{
...
  modules: [
  {
     dependencies: [{
      moduleA,
      moduleB
     }]
  },
  moduleA,
  moduleB
  ],
...
}

是版本升级的变化吗?

@dhlolo
Copy link

dhlolo commented Nov 28, 2021

我调试之后发现,Webpack5 compilation.modules的数据结构是这样的:

{
...
  modules: [
  {
     dependencies: [{
      moduleA,
      moduleB
     }]
  },
  moduleA,
  moduleB
  ],
...
}

是版本升级的变化吗?

不是的,一直都是这样,本来就是依赖图moduleGraph。图是松散结构,如果有多个入口的话,依赖一个module的话,多个树中都有这个module实例的引用,就可以做optimize,个人是这样理解

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

3 participants