webpack产出代码模块化浅析
13 Feb 2017
最近整理走读了一下webpack
产出的模块化代码,于是做一下记录,还没遇到过复杂的情况,只是浅析一下。
在写node代码的时候,模块化很自然,就是要封装模块的js,最后module.exports=xxx
,在引用的时候这样写即可require('xxx')
,而在浏览器端的情况下,一般封装模块的js最后会套上一层function
如下:
这个方法执行体在执行之后,将实际模块封装的对象存入module
。
而用webpack
产出的模块化代码基本是这样的。
这段代码是我用到了webpack抽取公共模块时产出的公共代码部分,里面包含了模块化的内容以及公共module。
可以看到方法是一个自执行函数,参数为modules (实际上,带入了moduleId为1的公共模块的函数)
定义了webpackJsonp
、__webpackRequire__
两个方法,为方便起见,简称wpJsonp
和wpRequire
, wpRequire
还有个ensure
属性方法,用于异步加载模块。
另外,还用上了两个变量installedModules
installedChunks
.
中间用到的id类参数有moduleId
和chunkId
。
通过走读代码,基本的联系图如下:
查看原图
入口文件entry以及需要异步加载的模块js都被编译成webpackJsonp()
的函数执行结构,wpJsonp
的主要作用,就是将模块的执行内容存放到modules中,以方便wpRequire
的时候,需要的模块能被找到执行体并初始化生成对应的module模块,在这个过程中,moduleId
就是模块执行体以及模块对象的索引值。
另外wpJsonp
还有一个逻辑是执行chunk的回调,即异步加载模块在加载完成并执行时,会触发执行wpRequire.ensure
时加入的回调内容。在这过程中,ensure主要负责的是:
- 将回调收集(模块正在加载中)
- 执行回调(之前已经加载过了)
- 开辟缓存位置(
installedChunks
)并启用script
加载js。
而chunkId
主要为入口文件或者异步加载文件的索引值。
代码走读过程比较绕,但经过整理一遍之后就明确了不少。
关于installedModules
变量,用于存储加载好的模块对象,当对应索引的内容为0时,没有含义,因为逻辑在判断if时发现没有模块,所以要去 加载模块,跟初始化时加载模块是一样的。而当加载完模块后,则会保存对应的module对象。
关于installedChunks
变量,用于标记chunk的加载状态,主要用于异步加载,当对应索引的内容为0时,表示该chunk已经加载过了,如果正在加载,则为数组(回调函数数组)。当chunk在 wpJsonp
执行时加载已经完成,其逻辑也会去判断回调,统一执行回调,并将对应标识置零。
编译结果内,会将用到的chunk都整理到ensure
的script加载逻辑内,根据chunkId来索引加载。