分析taro启动流程
-
@tarojs/cli
:
前述:taro build --type h5
通过本地node_modules/tarojs/cli/bin中执行taro.js文件const CLI = require('../dist/cli').default new CLI().run()
cli.ts
和commands/build.ts
- cli.ts
- cli: 调用run方法,run通过调用parseArgs方法去找到build命令,通过找到build命令前,先通过
new kernel
实例 - new kernel实例,传了options值,这个options值存在两个属性,appPath项目的根路径,presets是预设文件路径,预设好的指令和平台
const kernel = new Kernel({ appPath: this.appPath, presets: [ path.resolve(__dirname, '.', 'presets', 'index.js') ] })
build(kernel, { platform: args.type, isWatch: Boolean(args.watch), port: args.port, env: args.env, blended: Boolean(args.blended), // plugin: args.plugin, // release: args.release, isHelp: args.h })
- commands/build.ts中build方法被在cli.ts文件执行
-
@tarojs/service
:调用kernel
的run
方法参数,包括name
和platform
代表构建名和构建平台 -
run:方法
-
init:进行初始化:完成hooks,methods,commands和platforms指令库的装填完成;
-. initConfig 初始化配置文件:config/index.js
文件配置进行初始化后的文件对像,挂载到initialConfig
-. initPaths 初始化路径:获取项目根目录路径,node_modules路径,src路径,打包后输出dist文件路径,被挂载到paths
-. initPresetsAndPlugins: 初始化预设和插件,将presets和plugins通过mergePlugin
方法进行路径合并
-. resolvePresets和resolvePlugins方法,将预设的指令和平台挂载commands和platforms对象中,map对象- initPlugin中apply高阶函数调用,将插件中命令解析到commands(Map)和platforms(Map)库中,将插件类型库解析到commands和platforms库中
- 通过initPreset方法将presets中的文件解析装填到extraPlugins队列里
- 通过resolvePlugins方法将插件列表(小程序平台插件)和extraPlugins进行合并
- 通过initPlugin将commands和platforms库进行装填完成
- 通过initPluginCtx将hooks,methods,commands和platforms对库中指令进行注册
export function mergePlugins (dist: PluginItem[], src: PluginItem[]) { return () => { const srcObj = convertPluginsToObject(src)() const distObj = convertPluginsToObject(dist)() return merge(srcObj, distObj) } }
-
runWithPlatform
:通过这个方法完成获取平台类型对应的配置参数 -
applyPlugins
:通过这个方法去构建build指令,通过遍历hooks异步构建解析opts参数,采用const waterfall = tapable.AsyncSeriesWaterfallHook
方法异步传参;通过waterfall.toPromise
在循环内部调用每个hook.fn
,在循环外部waterfall.Promise
进行传参,无论循环内部循环多少次,都不会影响第二个回调参数的次数,在外部执行一次,内部第二个回调参数就只执行一次;参数即是初始配置化文件对象,这个hooks是通过初始化时通过presetsAndPlugins装填好的hooks库;const hooks = this.hooks.get(name) || []; const waterfall = new tapable_1.AsyncSeriesWaterfallHook(['arg']); if (hooks.length) { const resArr = []; for (const hook of hooks) { waterfall.tapPromise({ name: hook.plugin, stage: hook.stage || 0, // @ts-ignore before: hook.before }, (arg) => __awaiter(this, void 0, void 0, function* () { const res = yield hook.fn(opts, arg); if (constants_1.IS_MODIFY_HOOK.test(name) && constants_1.IS_EVENT_HOOK.test(name)) { return res; } if (constants_1.IS_ADD_HOOK.test(name)) { resArr.push(res); return resArr; } return null; })); } } return yield waterfall.promise(initialVal);
-
hook.fn
:初始化时对应的presets预设的配置文件的中fn回调函数,解析用户配置文件的,通过@tarojs/webpack-runner
包构建打包文件并进行输出对应的文件
总结:taro build --type h5
,中构建过程中@tarojs/cli
和@tarojs/service
只干了两件事,一是初始化,二是申请执行插件hook中的方法,以达到构建输出文件的目的;初始化,hooks库注册装填,plugins方法的注册,已到达methods库的装填,commands和platforms库注册装填。