本篇文章是 Taro 的源码解读系列的第五篇文章,下面是系列文章链接。
- Taro 源码解读 - @tarojs/taro 篇
- Taro 源码解读 - @tarojs/cli 篇
- Taro 源码解读 - taro build 篇
- Taro 源码解读 - miniRunner 篇
- Taro 源码解读 - TaroMiniPlugin 上篇
在上一篇文章 Taro 源码解读 - miniRunner 篇 中,已经讲解了 taro-cli
中 miniRunner
的工作流程,本质上是 webpack
构建流程。
本篇文章将会是对 miniRunner
篇的一个补充,着重介绍 miniRunner
中的 TaroMiniPlugin
。
话不多说,我们开始吧。
TaroMiniPlugin 概览
TaroMiniPlugin
是一个 webpack plugin
,根据 webpack
插件特性,在安装插件时,将会调用插件实例上的 apply
方法。而 apply
方法一般实现的都是在 webpack compiler
的不同生命周期中注册对应的钩子函数,用于在特定的时机处理额外的逻辑。
我们先来看看 TaroMiniPlugin
中的 apply
方法吧(如下图)
我们来分析 TaroMiniPlugin
的 apply
方法所做的事情,如下:
代码 | 分析 |
---|---|
第 148 - 156 行 |
获取插件传入的一些参数,获取入口文件路径 |
第 158 行 |
注册生命周期钩子函数,当 webpack 开始编译时执行 |
第 174 行 |
注册生命周期钩子函数,在 webpack 监听模式下,一个新的编译被触发之后执行 |
第 197 行 |
注册生命周期钩子函数,在 webpack 完成编译之前执行 |
第 211 行 |
注册生命周期钩子函数,在 compilation 创建成功之后执行,compilation 代表一次单独的编译 |
第 281 行 |
注册生命周期钩子函数,在 webpack 生成资源到 output 目录之前执行 |
第 288 行 |
注册生命周期钩子函数,在 webpack 生成资源到 output 目录之后执行 |
第 295 行 |
在注册完了生命周期钩子函数后,继续调用 TaroNormalModulesPlugin 插件的 apply 方法 |
接下来我们需要对 apply
注册的几个生命周期钩子函数进行解析。我们先看看 appEntry
的值,也就是我们的入口文件(如下图)。
生命周期钩子 - run
我们现在就从 TaroMiniPlugin
注册的一个钩子 run
开始解析,代码实现如下图
TaroMiniPlugin
使用 tapAsync
调用了一个异步钩子,钩子的名词是变量 PLUGIN_NAME
,也就是 TaroMiniPlugin
。
然后我们看到第 161
行,在这行代码中,调用了 TaroMiniPlugin
实例中的 run
方法,并将 compiler
作为参数传入。在 run
方法执行完成后,调用了 TaroLoadChunksPlugin
插件,这就是注册在 run
生命周期的钩子函数。
让我们来看看这个钩子函数中,一开始调用的 run
方法的实现吧。(如下图)
从上图代码的注释中,我们可以得知,run
方法所做的工作就是先分析 app
入口文件,再搜集页面、组件信息,最后再往 dependencies
属性中添加资源模块。
获取 AppConfig
进入到 run
方法,我们先来看看获取 app
配置这一步吧。这一步调用了 getAppConfig
方法,其实是分析 app.config.js
,也就是 Taro
官方提供的小程序配置文件。(如下图)
这里主要是收集了小程序的基础配置,除此之外,Taro
针对 usingComponents
注册的全局自定义组件做了处理,将其收集到了内部 components
属性中,以便后面使用。
最后收集到的配置类似于下图中展示的基础配置,然后将其存储在 TaroMiniPlugin
实例中的 appConfig
属性中。(如下图)
搜集小程序页面、组件信息
接下来,我们来看看 getPages
方法。(如下图)
在 getPages
方法中,主要做了这么几个工作:
代码行数 | 说明 |
---|---|
第 364 行 |
收集需要预渲染的页面 |
第 365 行 |
收集 tabbar 文件,主要是处理收集 tabbar 中的自定义组件 |
第 366 行 |
收集页面,存储在 pages 属性中 |
第 380 行 |
收集分包配置中的页面 |
在 getPages
方法中值得关注的是,pages
最后收集的属性不只是路径信息,还会分析出一些其他信息,譬如是否为小程序原生页面或组件、页面名称、页面文件路径...(如下图)
在页面全部搜集完成后,会对页面进行读取,并分析依赖关系,也就是 getPagesConfig
方法。(如下图)
在这一步中,主要是分析页面依赖的组件关系,并存储在 components
信息中。然后,就会出现我们熟悉的一个 Taro
编译启动提示界面啦~(如下图)
在分析完了页面组件之间的依赖关系后,会通过 getDarkMode
方法获取项目的 darkmode
配置,将主题信息存储在 TaroMiniPlugin
实例的 themeLocation
属性中。
收集依赖关系
在收集完了小程序页面配置文件和组件文件后,进入到下一步,进行一些依赖关系的收集。
我们先来看看 getConfigFiles
方法。(如下图)
从上图可以看出,该方法会从 fileConfigs
中取出所有配置,然后将其添加到 dependencies
中。然后,注册了一个 webpack
钩子函数,在创建 chunk assets
之前,把所有的 config
相关 chunk
移除。
在依赖收集完成后,dependencies
是一个 Map
实例,记录了 config
配置文件的相关信息。(如下图)
在 config
文件收集完成后,又通过 addEntries
将 app、模板组件、页面、组件等资源模块信息,都记录在了 dependencies
中。(如下图)
到了这里,run
方法流程执行完成,将项目中一些基础的页面、组件、依赖关系都收集完成。并且,将这些信息记录在 TaroMiniPlugin
实例中,然后将资源模块相关信息记录在 dependencies
属性中。
在 TaroMiniPlugin
插件中,遵循了 单一职责
设计原则,在 run
方法中基本上只做了项目信息收集的工作,并没有做任何产生副作用的操作。遵循 单一职责
设计原则,可以使 TaroMiniPlugin
的工作流程变得更加清晰,也让我们的源码阅读更加简单 (* ̄︶ ̄).
TaroLoadChunksPlugin
在 run
钩子时,除了运行 run
方法收集完了项目相关基础信息以外,还调用了另一个插件 TaroLoadChunksPlugin
。
这个插件的主要作用就是处理项目中需要提取的公共文件。具体内容可以参考 Taro-commonChunks、webpack-runtimeChunk、webpack-spiltChunks。
小结
以上就是 TaroMiniPlugin
中注册的第一个钩子 run
所做的事情,这个钩子函数将会在开始编译时执行,主要所做的事情就是将项目中一些基础的页面、组件、依赖关系收集完成,记录在 TaroMiniPlugin
中,以便在后面的编译步骤中使用。
在后面的文章中,我们将陆续对 TaroMiniPlugin
中注册的其他 webpack
钩子进行详细解析,如庖丁解牛般将 TaroMiniPlugin
源码清晰解读。
最后一件事
如果您已经看到这里了,希望您还是点个赞再走吧~
您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!
如果觉得本文对您有帮助,请帮忙在 github 上点亮 star
鼓励一下吧!