Because of the recent use of TARO to write small procedures, out of curiosity, ready to read the source code of TARO.

First pull the latest Taro source code from the official website, version number is 3.0.18, the source directory is as follows:

The catalogs are nothing special, let’s focus on the core packages in the Packages catalog (as shown below)

These core packages make up Taro and enable the multi-platform build of Taro.

The module for this parsing is the Tarojs/CLI section, so let’s get started.

Taro command

Packages /taro-cli/bin/taro Packages /taro-cli/bin/taro Packages /taro-cli/bin/taro Packages /taro-cli/bin/taro Packages

As you can see from the figure above, the entry file creates a new CLI instance and then runs the run command.

The Kernel of Kernel

Let’s look directly at the CLI example (as shown below)

As you can see from the figure above, the implementation of the CLI example is relatively simple. All the run command does is parse the command-line argument -parseargs.

After the parameters are parsed, a new instance of the Kernel(Kernel is the soul of @taro/cli, which we’ll discuss later) is created, and the project is created using this Kernel(as shown in the figure below).

The init method called in line 58 actually calls the method, so let’s take a look at this method (as shown below).


The implementation of the run method is complex, and we need to perform a line-by-line analysis, starting with the kernel.init() method in line 266 (as shown below).

In the init method above, the initConfig method initializes the project configuration; The InitPaths method initializes the basic project paths, such as the project directory (APPPath), the dependency directory (NodeModulePath), and the project configuration file (ConfigPath).

The kernel initPresetsAndPlugins method is the key, we need to take a closer look at the code (pictured)

In the code above:

  • The first89 ~ 90Line, all presets and plug-in collections are collected.
  • The first91For the linerequireMethod is registeredbabelI’m going to put a hook on it. Thereafter, whenever usedrequireWhen files with.js,.jsx,.es, and.es6 suffixes are loaded, they are transcoded with Babel first. -Babel’s introductory tutorial
  • The first97 ~ 98Line, all of which are loadedpresetspluginIn the endpluginForm registration tokernel.pluginsIn the collection.

Plugins are just collections of presets and plugins, each and every one of them
pluginThey all contain one
applyFunction executed to export the corresponding
PluginThe module. (as shown below)

Initialize the Kernel plug-in process

Let’s take a look at the process of initializing a Kernel plug-in (as shown below).

First, at line 140, initialize the CTX (context) of the plug-in. The initPluginctX method returns a Proxy object (as shown below).

As you can see from the figure above, this method creates a new instance of Plugin, and then creates a Proxy based on this instance. When accessing the properties of this instance, the method in the methods object is returned first, and then the instance method of this is overwritten.

Then let’s go back to the method shown below and continue parsing

In the code above, line 141, execute the exported plug-in (module) function with PluginctX as the input parameter.

Let’s take WeChat platform as an example. In WeChat platform, the corresponding apply function looks like this (as shown in the figure below) :

As can be seen in the diagram above, the method exported in Weapp in turn calls the ctx.registerPlatform method for platform registration, which is also the well-known Inversion of Control (IOC) pattern in the design pattern.


Let’s take a look at what the attributes of the Kernel look like after the initPresetsAndPlugins method is completed.


The methods shown below, which look familiar, are the APIs used to modify the compilation process in the documentation for extending the Taro plug-in.

Let’s take a look at how to write a plug-in in the official documentation (see below).

Looks a lot like the plugin we saw above for WeChat


Next let’s look at hooks (see figure below)

The hooks command is also familiar. It is the same command that you would use when using taro-cli, which will call the corresponding hook on the corresponding execution command.


Next, let’s look at Platforms (pictured below)

Platforms include compiled code for each platform to convert the React, Vue syntax into the corresponding platform syntax.


Finally, let’s look at commands (Figure below)

You can see that commands correspond to the Taro scaffold’s built-in commands.

Kernel lifecycle hooks

At this point, the Kernel is basically assembled and enters the Kernel’s lifecycle hooks.

The first two life-cycle hooks of the Kernel are onReady and onStart, which do not perform operations. Developers can register the corresponding hooks when they write their own plug-ins.

After executing the above two hooks, the Kernel begins to execute the init hook (as shown below).

We need to go through the above code line by line:

  • The first233Line: One is createdPipeline - AsyncSeriesWaterFallHookProject for sequential execution of asynchronous tasks,AsyncSeriesWaterfallHookThe implementation oftapableLibrary (as shown below)

  • The first237Cycle:hooksArray to register all hooks withwaterfallIn the.
  • The first255OK: Perform pipelined tasks.

After the above analysis, we can basically understand the execution process of TARO-CLI.

Init hooks

Now go to the Kernel’s init hook (as shown below).

The init hook finally calls project.create() to start creating a new project. On the command line there is the following prompt (as shown in the figure below) :

The greeting you see above is actually the init function in the Project instance in the code (see below).

As you can see from the figure above, the ask function is also called on line 78, and the ask function corresponds to the ask option when creating a new project (see figure below).

TaroAnd many of the scaffold’s command-line interaction functions are through
inquirerLibrary implementation.

After the options are confirmed, the remote template will be pulled through Git (as shown below)

And we can also find a corresponding template warehouse in the Taro official (as shown below).

Let’s open one of these files at random, such as package.json (as shown below).

As you can see from the figure above, the file in the template file repository is the suffix name of TMPL, which is then overwritten to the corresponding configuration file for different configuration items through the template syntax similar to EJS (figure below).

As can be seen from the above figure, the file is finally written to the directory through the createApp function in the create to complete the creation of the project.

Once the project is created, the dependency is installed automatically, and you are done. The init hook is executed!

After the init completes, the taro init command completes and a new taro project has been created.

Finally, let’s draw a flowchart to help you understand.


To this point, @tarojs/cli has been resolved to complete, this part of the source code implementation is more insitive, using Kernel + registered plug-in + lifecycle hook function implementation, flexible implementation of various different command combinations.

Some children may have guessed, the use of TARO development of different platform build command, such as WeChat applet build command TARO build -type ammunition, is also implemented by Kernel + hook. The build hook is called and the platform-specific compiler Plugin is called. If you are interested in this part of the code, you can read it yourself

One last thing

If you’ve already seen this, I hope you’ll like it before you go

Your thumb up is the greatest encouragement to the author, and can also let more people see this article!

If you found this article helpful, please help to light up Star on GitHub.