前言
本文首發(fā)簡書,源碼看到哪就更新到哪。
項(xiàng)目概覽
lerna
taro 用 lerna 做多模塊管理,lerna 多見于中大型項(xiàng)目,比如 babel。
taro 想要在開發(fā)環(huán)境下跑起來,只需要:
cd taro目錄
npm i
npm run bootstrap => npm-run-all clear-all bootstrap:lerna
npm run bootstrap 做了兩個(gè)事情:
-
clear-all
清理所有的舊依賴
rimraf package-lock.json packages/*/node_modules packages/*/package-lock.json -
bootstrap:lerna
初始化 lerna
lerna bootstrap -- --ignore-engines(--ignore-engines 這個(gè)參數(shù)是給 npm client 的)
其中第二步 bootstrap:lerna 具體做了:
-
npm installall external dependencies of each package. - Symlink together all Lerna
packagesthat are dependencies of each other.
這一步尤其重要,因?yàn)槎嗄K開發(fā)最煩人的問題就是開發(fā)的時(shí)候模塊間可能會(huì)互相依賴,如果本地的模塊符合指定版本的話,lerna 會(huì)自動(dòng)幫你軟鏈上,不然就會(huì)去 npm 下載。值得留意的是, 如果有A依賴了一個(gè)小于當(dāng)前版本的B,也就是說本地這個(gè)B版本更高,lerna會(huì)自動(dòng)幫你去下載舊的那個(gè)版本B,所以版本問題你也不用操心了。 -
npm run prepublishin all bootstrapped packages. -
npm run preparein all bootstrapped packages.
參考
- lerna bootstrap
taro-cli
腳手架工具,用于初始化 taro 項(xiàng)目,編譯成多端平臺(tái)代碼
bin/taro
先從入口文件 bin/taro 說起,項(xiàng)目用了 tj/commander,這可以說是 tj 大神在 js 叱咤風(fēng)云時(shí)的一大杰作,靈感來源于 ruby 的 commander。
taro 使用了像 git 一樣的子命令,taro init xxx,在 commander 你只需要在 bin/ 目錄下,創(chuàng)建對(duì)應(yīng)的 program-command 文件即可,比如 taro-init,taro-build 等。
bin/taro-init
taro-init 文件就是傳遞命令行的參數(shù)進(jìn)去,無需介紹太多,重點(diǎn)在于我是怎么一步一步看代碼的。
node 現(xiàn)在 debug 已經(jīng)很方便,方法如下:
node --inspect-brk ~/wip/to-be-read/taro/packages/taro-cli/bin/taro-init myApp # 找到入口文件,像教程一樣開始新手教學(xué)
chrome://inspect # 打開 chrome,輸入,找到 remote target 點(diǎn)擊進(jìn)去即可
簡單理一下 init 的過程:
- Project.new
- .ask (
return inquirer.prompt(prompts)) 詢問用戶各種配置 - .ask 返回的配置賦值給 project.conf
- .ask (
- Project.write
-
const templateCreate = require(path.join(this.templatePath(), template, 'index.js'))動(dòng)態(tài)加載對(duì)應(yīng)的 template 的index.js文件 - 然后傳參 (project.conf) 進(jìn)去初始化,生成對(duì)應(yīng)的模板文件
-
bin/taro-build
不同的端對(duì)應(yīng)的邏輯在:
- h5.js
- weapp.js - swan
- weapp.js - alipay
- weapp.js - weapp
- rn.js
- ui.js (專門給 taro-ui 用的)
weapp build 大致過程
-
buildProjectConfig()
復(fù)制 taro 根目錄下的project.config.json到dist/,并把miniprogramRoot改成./, 這樣就可以把dist/拖到微信開發(fā)者工具,而不是整個(gè)taro 項(xiàng)目,解決了頻繁編譯問題
-
copyFiles()
小程序編譯增加 copy 功能,用于把taro項(xiàng)目的資源拷貝到對(duì)應(yīng)的端
參考:
- https://github.com/coolzilj/taro/commit/0132a0ecda029b3bac2b3cf605e6e67193fec37d
- 配置詳情 · Taro
- buildEntry()
編譯入口文件(src/app.js)
具體步驟如下:
- fs 讀取入口文件的代碼,等到字符串
entryFileCode - @tarojs/transformer-wx 轉(zhuǎn)換
entryFileCode得到transformResult(把 Nerv 組件轉(zhuǎn)換為小程序代碼) -
parseAst(transformResult.ast)解析入口文件 ast 得到 res - compileScriptFile(res.code) 得到 resCode,就是編譯好的 app.js
- buildPages()
Babel
一般來說,將一種結(jié)構(gòu)化語言的代碼編譯成另一種類似的結(jié)構(gòu)化語言的代碼包括以下幾個(gè)步驟:

參考:
- https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md
- http://www.alloyteam.com/2017/04/analysis-of-babel-babel-overview/
- https://www.h5jun.com/post/babel-for-es6-and-beyond.html
- https://astexplorer.net/
@tarojs/transformer-wx
該模塊的功能主要是把 Nerv 組件轉(zhuǎn)換為小程序代碼。
在研究這個(gè)模塊的時(shí)候,最好打開 https://astexplorer.net/ 對(duì)照著看。
首先是 src/app.js 入口文件