1

本篇文章是 Taro 的源码解读系列的第五篇文章,下面是系列文章链接。

在上一篇文章 Taro 源码解读 - miniRunner 篇 中,已经讲解了 taro-climiniRunner 的工作流程,本质上是 webpack 构建流程。

本篇文章将会是对 miniRunner 篇的一个补充,着重介绍 miniRunner 中的 TaroMiniPlugin

话不多说,我们开始吧。

TaroMiniPlugin 概览

TaroMiniPlugin 是一个 webpack plugin,根据 webpack 插件特性,在安装插件时,将会调用插件实例上的 apply 方法。而 apply 方法一般实现的都是在 webpack compiler 的不同生命周期中注册对应的钩子函数,用于在特定的时机处理额外的逻辑。

我们先来看看 TaroMiniPlugin 中的 apply 方法吧(如下图)

image

我们来分析 TaroMiniPluginapply 方法所做的事情,如下:

代码分析
148 - 156获取插件传入的一些参数,获取入口文件路径
158注册生命周期钩子函数,当 webpack 开始编译时执行
174注册生命周期钩子函数,在 webpack 监听模式下,一个新的编译被触发之后执行
197注册生命周期钩子函数,在 webpack 完成编译之前执行
211注册生命周期钩子函数,在 compilation 创建成功之后执行,compilation 代表一次单独的编译
281注册生命周期钩子函数,在 webpack 生成资源到 output 目录之前执行
288注册生命周期钩子函数,在 webpack 生成资源到 output 目录之后执行
295在注册完了生命周期钩子函数后,继续调用 TaroNormalModulesPlugin 插件的 apply 方法

接下来我们需要对 apply 注册的几个生命周期钩子函数进行解析。我们先看看 appEntry 的值,也就是我们的入口文件(如下图)。

image

生命周期钩子 - run

我们现在就从 TaroMiniPlugin 注册的一个钩子 run 开始解析,代码实现如下图

image

TaroMiniPlugin 使用 tapAsync 调用了一个异步钩子,钩子的名词是变量 PLUGIN_NAME,也就是 TaroMiniPlugin

然后我们看到第 161 行,在这行代码中,调用了 TaroMiniPlugin 实例中的 run 方法,并将 compiler 作为参数传入。在 run 方法执行完成后,调用了 TaroLoadChunksPlugin 插件,这就是注册在 run 生命周期的钩子函数。

让我们来看看这个钩子函数中,一开始调用的 run 方法的实现吧。(如下图)

image

从上图代码的注释中,我们可以得知,run 方法所做的工作就是先分析 app 入口文件,再搜集页面、组件信息,最后再往 dependencies 属性中添加资源模块。

获取 AppConfig

进入到 run 方法,我们先来看看获取 app 配置这一步吧。这一步调用了 getAppConfig 方法,其实是分析 app.config.js,也就是 Taro 官方提供的小程序配置文件。(如下图)

image

这里主要是收集了小程序的基础配置,除此之外,Taro 针对 usingComponents 注册的全局自定义组件做了处理,将其收集到了内部 components 属性中,以便后面使用。

最后收集到的配置类似于下图中展示的基础配置,然后将其存储在 TaroMiniPlugin 实例中的 appConfig 属性中。(如下图)

image

搜集小程序页面、组件信息

接下来,我们来看看 getPages 方法。(如下图)

image

getPages 方法中,主要做了这么几个工作:

代码行数说明
364收集需要预渲染的页面
365收集 tabbar 文件,主要是处理收集 tabbar 中的自定义组件
366收集页面,存储在 pages 属性中
380收集分包配置中的页面

getPages 方法中值得关注的是,pages 最后收集的属性不只是路径信息,还会分析出一些其他信息,譬如是否为小程序原生页面或组件、页面名称、页面文件路径...(如下图)

image

在页面全部搜集完成后,会对页面进行读取,并分析依赖关系,也就是 getPagesConfig 方法。(如下图)

image

在这一步中,主要是分析页面依赖的组件关系,并存储在 components 信息中。然后,就会出现我们熟悉的一个 Taro 编译启动提示界面啦~(如下图)

image

在分析完了页面组件之间的依赖关系后,会通过 getDarkMode 方法获取项目的 darkmode 配置,将主题信息存储在 TaroMiniPlugin 实例的 themeLocation 属性中。

收集依赖关系

在收集完了小程序页面配置文件和组件文件后,进入到下一步,进行一些依赖关系的收集。

我们先来看看 getConfigFiles 方法。(如下图)

image

从上图可以看出,该方法会从 fileConfigs 中取出所有配置,然后将其添加到 dependencies 中。然后,注册了一个 webpack 钩子函数,在创建 chunk assets 之前,把所有的 config 相关 chunk 移除。

在依赖收集完成后,dependencies 是一个 Map 实例,记录了 config 配置文件的相关信息。(如下图)

image

config 文件收集完成后,又通过 addEntries 将 app、模板组件、页面、组件等资源模块信息,都记录在了 dependencies 中。(如下图)

image

到了这里,run 方法流程执行完成,将项目中一些基础的页面、组件、依赖关系都收集完成。并且,将这些信息记录在 TaroMiniPlugin 实例中,然后将资源模块相关信息记录在 dependencies 属性中。

TaroMiniPlugin 插件中,遵循了 单一职责 设计原则,在 run 方法中基本上只做了项目信息收集的工作,并没有做任何产生副作用的操作。遵循 单一职责 设计原则,可以使 TaroMiniPlugin 的工作流程变得更加清晰,也让我们的源码阅读更加简单 (* ̄︶ ̄).

TaroLoadChunksPlugin

run 钩子时,除了运行 run 方法收集完了项目相关基础信息以外,还调用了另一个插件 TaroLoadChunksPlugin

这个插件的主要作用就是处理项目中需要提取的公共文件。具体内容可以参考 Taro-commonChunkswebpack-runtimeChunkwebpack-spiltChunks

小结

以上就是 TaroMiniPlugin 中注册的第一个钩子 run 所做的事情,这个钩子函数将会在开始编译时执行,主要所做的事情就是将项目中一些基础的页面、组件、依赖关系收集完成,记录在 TaroMiniPlugin 中,以便在后面的编译步骤中使用。

在后面的文章中,我们将陆续对 TaroMiniPlugin 中注册的其他 webpack 钩子进行详细解析,如庖丁解牛般将 TaroMiniPlugin 源码清晰解读。

最后一件事

如果您已经看到这里了,希望您还是点个赞再走吧~

您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!

如果觉得本文对您有帮助,请帮忙在 github 上点亮 star 鼓励一下吧!

image


晒兜斯
1.8k 声望534 粉丝