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