因为近期使用到 Taro 编写小程序,出于好奇,准备研读一下 Taro 的源码。
在上一篇文章 Taro 源码解读 - @tarojs/cli 篇 中,已经讲解了 taro-cli
的实现原理,然后以 taro init
为案例解释了核心 Kernel
+ 钩子的运行机制。
本篇文章将会是对 @tarojs/cli
篇的一个补充,着重介绍 taro build
的运行机制,以及不同平台的编译差别。
话不多说,我们开始吧。
taro build
我们首先来看看在一个 Taro
项目中 package.json
的 scripts
部分(如下图)
从上图可以看出,taro build
命令主要的参数是 type
,在 dev
模式下,会增加一个额外的 watch
参数。
基于这个印象,我们来看看运行 taro build
后会发生什么吧~
Kernel
首先,Cli
实例将会对命令行参数进行解析,然后进入到 build
操作(如下图)
在上图的第 41
行运行的 build
函数,实际上是运行了 kernel.run()
函数(如下图)
我们再来解析一下 kernel.run()
函数所做的事情吧~
kernel.run
这一段是Kernel
的核心内容,理解了这段就理解了taro-cli
的工作模式
下图是 kernel.run
方法,我们来进行逐行分析(如下图)
- 第
271~279
行:初始化一些参数; - 第
280
行:初始化项目配置、初始化项目路径信息、初始化项目插件;这一步是非常关键的准备工作,在执行完成后,所有的编译插件、平台编译插件都将被加载到Kernel
实例上,供后续的编译程序使用。在装载完成后,将会触发Kernel
的第一个钩子 -onReady
。(在 Taro 源码解读 - @tarojs/cli 篇 篇中有详细讲解) - 第
281
行:执行第二个钩子 -onStart
; 第
297~303
行:这里的opts.platform
其实就是运行taro build
时传入的type
参数,比如weapp、qq、h5...
。然后根据平台获取对应的编译配置(如下图)在上图中的
framework
中是项目所使用的框架react
,而platform
则是目标编译平台weapp
(微信小程序)。- 第
304
行:运行第三个钩子,也就是kernel.run
函数传入的钩子 -build
钩子。
build 钩子
我们下面来看看 build
钩子函数(如下图)
从上图可以看出,build
钩子有我们比较熟悉的参数,比如 --type
、--watch
,还有一些比较少用到的,这里就不作展开了。
这里我们重点关注 fn
函数,当钩子被触发时,就是执行了 fn
函数(如下图)。
从上图可以看出,fn
的实现并不复杂,我们来分析一下其中几行关键代码:
- 第
30
行:检查项目相关配置,这里检查的配置文件其实就是项目中的config/index.js
配置文件。 - 第
60
行:构建开始,触发onBuildStart
钩子。这个钩子在文档中也有介绍,可以通过插件对代码编译过程进行拓展(如下图)。 - 第
61
行:触发对应的平台钩子,在本案例中是weapp
钩子(如下图);
weapp 钩子
Taro
的钩子机制实现的非常精妙,同时也使我们的源码阅读变得更加方便,那么我们只需要找到对应的 weapp
文件即可,这里我们直接关注 fn
函数。(如下图)
我们来解析其中几行关键代码:
- 第
45
行:根据项目配置生成微信小程序的project.config.json
; - 第
51
行:准备miniRunner
配置参数,其实就是微信小程序对应的编译参数,我们可以从配置里看到比较熟悉的微信小程序文件(如下图) - 第
69、70
行:加载miniRunner
包,并运行miniRunner
。
miniRunner 小窥
在最后,taro build
从 kernel.run
走到了 miniRunner
,那 miniRunner
是什么呢?
有的小伙伴应该已经猜到了,就是 webpack
编译程序。(如下图)
在收集好对应配置后,最后进入到了 webpack
编译代码(如下图)
经过编译后,我们对应平台的小程序代码就被编译出来啦!
小结
在本章 taro build
中,我们更加能体会到 Kernel
+ 钩子机制的精妙之处。这种实现解耦了模块,使得模块之间得以分治。
最后的 miniRunner
可以说是 taro build
中编译过程的最后一步。这部分的实现应该不算 Taro
源码解读的部分,更像是 webpack
的使用解读。
所以,我们后面将会使用一篇独立的章节来讲解 miniRunner
所做的工作,以及它是如何将 React、Vue
代码编译成小程序端代码的。
最后一件事
如果您已经看到这里了,希望您还是点个赞再走吧~
您的点赞是对作者的最大鼓励,也可以让更多人看到本篇文章!
如果觉得本文对您有帮助,请帮忙在 github 上点亮 star
鼓励一下吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。