taro 腳手架分別有:javascript
本章主要講解前面五個的功能和實現,而build
和convert
則會放在taro-cli
原理系列的二和三,敬請期待~ 因爲 官方也在維護,代碼可能會更新,所以文中的代碼不免會與最新源碼有出入, 本文所解析taro-cli
的version
爲1.3.21
,將來若是某些功能的分析文章與源碼若是出入過大,則會更新對應的文章。css
首先咱們看一下taro-cli的目錄,該工程位於taro的packages目錄下。當咱們安裝taro-cli後,會生成taro 命令。 html
當咱們在命令行中輸入Taro
時,會有如下的輸出:vue
�👽 Taro v1.2.13
Usage: taro <command> [options] ource\\todoList-Redux\\
Options: de
-V, --version output the version number
-h, --help output usage information
Commands: postinstall || echo \" init [projectName] Init a project with default templete build Build a project with options update Update packages of taro convert Convert weapp to taro info Diagnostics Taro env info help [cmd] display help for [cmd] 複製代碼
那麼,像@vue/cli
,@wepy/cli
等,是如何讓咱們能夠直接在命令行中使用呢?
緣由在於, @taro/taro-cli
的package.json
中的bin
字段:java
"bin": {
"taro": "bin/taro"
}
複製代碼
上面代碼指定,taro 命令對應的可執行文件爲 bin 子目錄下的 taro.js。Npm會尋找這個文件,在node_modules/.bin/目錄下創建符號連接。在上面的例子中,taro.js會創建符號連接npm_modules/.bin/taro。因爲node_modules/.bin/目錄會在運行時加入系統的PATH變量,所以在運行npm時,就能夠不帶路徑,直接經過命令來調用這些腳本。若是隻有一個命令,也能夠直接簡寫成string,前提是命令名稱和模塊名稱同樣
。node
{
"name": "taro",
"version": "1.2.5",
"bin": "bin/taro"
}
複製代碼
使用命令建立模板項目git
taro init myApp
// npx @tarojs/cli init myApp
複製代碼
其中用到了commander
這個庫,能夠自動的解析命令和參數,合併多選項,處理短參等等。讓咱們來看一下它在init
命令中的用法:github
// taro-cli/bin/taro-init
const program = require('commander')
program
.option('--name [name]', '項目名稱')
.option('--description [description]', '項目介紹')
.option('--typescript', '使用TypeScript')
.option('--no-typescript', '不使用TypeScript')
.option('--template-source [templateSource]', '項目模板源')
.option('--clone [clone]', '拉取遠程模板時使用git clone')
.option('--template [template]', '項目模板')
.option('--css [css]', 'CSS預處理器(sass/less/stylus/none)')
.parse(process.argv)
const { template, templateSource, clone, description, name, css } = program;
const project = new Project({
projectName,
projectDir: process.cwd(),
templateSource,
clone,
template,
description,
typescript,
css
})
複製代碼
代碼較短,相信你們看了也是一目瞭然。這裏就不詳細說明。 重點講一下,new Project
和 project.create()
所作的事情。typescript
// taro-cli/src/create/project.ts
class Project extends Creator {
constructor (options: IProjectConf) {
super(options.sourceRoot)
this.conf = Object.assign({
projectName: '',
projectDir: '',
template: '',
description: ''
}, options)
}
}
複製代碼
new Project
時,在構造函數中傳進咱們經過命令行輸入的參數,好比 -- description
。緊接着咱們看一下create作了什麼事情。shell
create () {
this.fetchTemplates()
.then((templateChoices: string[]) => this.ask(templateChoices))
.then(answers => {
const date = new Date()
this.conf = Object.assign(this.conf, answers)
this.conf.date = `${date.getFullYear()}-${(date.getMonth() + 1)}-${date.getDate()}`
this.write()
})
.catch(err => console.log(chalk.red('建立項目失敗: ', err)))
}
複製代碼
git clone
的方式下載(這裏是使用了download-git-repo
這個庫)1.3.9 開始 Taro 會在用戶根目錄下建立 .taro 文件夾,其中 .taro/index.json 用於存放 CLI 相關配置。 開發者可使用 taro config 命令對配置項進行一系列操做。說明
ask
(詢問),便是經過inquirer
模塊,創造命令行交互,肯定(項目名,描述,是否用ts, css預處理器,模板)mem-fs-editor
的copyTpl
拷貝模板,模板使用ejs,並將所須要的選項傳遞進去。好比修改package.json中的name和description。git init
初始化倉庫和
npm install
來安裝依賴(固然,也多是使用yarn源或者cnpm來安裝),如下是判斷使用哪一個registry的代碼
if (shouldUseYarn) {
command = 'yarn install'
} else if (helper.shouldUseCnpm()) {
command = 'cnpm install'
} else {
command = 'npm install'
}
export function shouldUseYarn (): boolean {
try {
execSync('yarn --version', { stdio: 'ignore' })
return true
} catch (e) {
return false
}
}
複製代碼
快速建立新頁面
Taro create --name [頁面名稱] 複製代碼
可以在當前項目的pages目錄下快速生成新的頁面文件,並填充基礎代碼,是一個提升開發效率的利器。
create的過程與init相似,這裏就不作過多的闡述.
檢查原子化服務規範
) 下面,咱們分別講講各個validator的功能與實現:使用joi
(The most powerful data validation library for JS),對config目錄下的配置作校驗。
/**
*projectConfig: config文件夾下的配置
*configSchema: joi配置
*/
export default async function ({ configPath, projectConfig }) {
const { error } = Joi.validate(projectConfig, configSchema, { abortEarly: false })
return buildReport(configPath, error)
}
複製代碼
這裏咱們也看一下JOI的簡單用法。如下兩個字段示例,定義了類型,以及是否必填
const schema = Joi.object().keys({
'projectName': Joi.string().required(),
'date': Joi.date()
})
複製代碼
依賴檢查主要有三個方面:
errorLines = _.concat(errorLines, pkgsNotInstalled(pkgs))
errorLines = _.concat(errorLines, taroShouldUpdate(taroPkgs))
errorLines = _.concat(errorLines, taroCliVersionNotMatch(taroPkgs))
複製代碼
recommandValidator 檢查的是一些常見的推薦內容。主要有:
前三項文件配置的檢查,是經過fs.readdirSync('./')
獲取項目文件,並匹配。而eslint和測試的檢查,則是經過檢查是否有安裝了相關的依賴包。
檢查 ESLint,該Validator是對代碼作了一遍eslint的檢查。使用eslint的 CLIEngine
模塊
import { CLIEngine } from 'eslint'
const eslintCli = new CLIEngine({
cwd: process.cwd(),
useEslintrc: false,
configFile
})
...
const report = eslintCli.executeOnFiles([sourceFiles])
const formatter = eslintCli.getFormatter()
複製代碼
這個validator是用於對華爲原子服務定義文件的校驗。快應用這一塊小編並不瞭解,想詳細學習的能夠去developer.huawei.com看一下。
檢查是否有project.quickapp.json
文件,若是有的話則對ability.xml
作檢驗。如下是abilityXMLValidator.ts中的註釋,小編就直接CV過來啦~~~
Taro 提供了命令來一鍵檢測 Taro 環境及依賴的版本等信息,方便你們查看項目的環境及依賴,排查環境問題。在提 issue 的時候,請附上 taro info 打印的信息,幫助開發人員快速定位問題。
如下是taro info
的核心代碼,主要是使用到了envinfo
這個庫
async function info (options) {
const info = await envinfo.run(Object.assign({}, {
System: ['OS', 'Shell'],
Binaries: ['Node', 'Yarn', 'npm'],
npmPackages,
npmGlobalPackages: ['typescript']
}, options), {
title: `Taro CLI ${getPkgVersion()} environment info`
})
console.log(info)
}
複製代碼
envinfo.run
這個方法接受須要的env Info的參數,返回具體的參數值。
更新項目中 Taro 相關的依賴
taro update project
複製代碼
const getLatestVersion = require('latest-version')
複製代碼
// 寫入package.json
try {
await fs.writeJson(pkgPath, packageMap, {spaces: '\t'})
console.log(chalk.green('更新項目 package.json 成功!'))
console.log()
} catch (err) {
console.error(err)
}
複製代碼
let command
if (shouldUseYarn()) {
command = 'yarn'
} else if (shouldUseCnpm()) {
command = 'cnpm install'
} else {
command = 'npm install'
}
const child = exec(command)
const spinner = ora('即將將項目全部 Taro 相關依賴更新到最新版本...').start()
child.stdout.on('data', function (data) {
spinner.stop()
console.log(data)
})
child.stderr.on('data', function (data) {
spinner.stop()
console.log(data)
})
複製代碼
這裏的exec使用了child_process
模塊,exce
也提供了回調,所以,也能夠這樣子寫:
exec(command, (error, stdout, stderr) => {
if (error) {
console.log(error)
} else {
console.log(`${stderr}${stdout}`)
}
})
複製代碼
關於taro-cli的實現:
咱們藉助nodejs,經過用戶輸入的命令和命令行與用戶的交互,來建立文件
,建立頁面
,項目診斷
,編譯
,更新
等等。其中,由commander
,inquire
模塊來處理輸入參數。
taro-cli的亮點,是多了一個doctor的東西,按照以往的經驗,根據一個推薦化的配置來檢查項目,減小咱們的犯錯機會,這是十分值得稱讚的。這其中不少技術細節值得咱們去深刻挖掘~
下一篇預告: 【源碼解析】taro-cli(2) - build