最近在用taro做小程序, 还是比较喜欢cli带的create命令, 能直接创建页面, 但是功能也比较薄弱
我是使用vue3的, 但是创建的还是option样式, 便想能不能支持自定义
首先看create都接收哪些参数, 前提是你要安装@taro/cli
taro create -h
得到的结果是
$ taro create -h
👽 Taro v3.6.8
Usage: taro create [options]
Options:
--name [name] 名称
--description [description] 介绍
--type [type] 模版类型(page(默认)|plugin-command|plugin-build|plugin-template)
-h, --help output usage information
Synopsis:
$ taro create page
$ taro create --name=page --description=desc
$ taro create my-plugin --type=plugin-command
目前看是也比较少, 然后就clone taro的工程源码来看一下
项目也是使用pnpm-workspace做的monorepo, 这个我们在前面的系列文章中有讲到这个, 不了解的可以翻回去看下
package 目录下的内容还是比较多的, 我们进入到 taro-cli 这个目录,
先看下package.json中的main字段, 是 index.js, 然后index.js中又指向了
module.exports = require('./dist/index.js').default
这里指向的是构建后的产物, 然后看了一眼package.json中的build
"build": "pnpm run clean && pnpm run prod",
"prod": "tsc",
"clean": "rimraf dist"
调用的就是先删除原来的构建产物再调用tsc命令, 这里会取读当前子项目根目录的tsconfig.json, 里面内容也比较简单, 都是默认的配置, 源码目录是 ./src, 那么我们就去src下看看, 直接看index.ts会有点晕, 只是导出了一些类和函数, 我们注意到还有个 ./bin, 每次使用 taro 都会先调用 printPkgVersion() 函数输出
console.log(`👽 Taro v${taroVersion}`)
结果就是咱们上面输出结果的第一行了, 然后是实例化一个 CLI 类, 然后调用 run()
run () {
return this.parseArgs()
}
这个就是解析参数, 往下看, 这里用到了一个 minimist()函数来解析参数,
看仓库简单写个demo
var argv = require('minimist')(process.argv.slice(2));
console.log(argv);
node main.js create -h
得到的结果是
{ _: [ 'create' ], h: true }
如果
node main.js create -help
会得到什么呢? 是
{ _: [ 'create' ], h: true, e: true, l: true, p: true }
有点出乎意料, 这里也大概明白为什么很多cli 单横线 都会只跟单字母了 大致了解了就是解析得到了action和参数, 这时我们再回去看 package.json下是有一个
"bin": {
"taro": "bin/taro"
},
这个是指定了这个功能是一个可执行文件, taro 等同于 node taro
接着看 parseArgs()
const _ = args._
const command = _[0]
我们的command 就是 create
剩下的代码也使用create来往下看,
判断如果是 h 则打印日志, 如果是v 则打印版本, 如果什么也不是, 那么就什么也不做,
我们的create 进入了方法 customCommand()
kernel.run({
name: command,
opts: {
_: args._,
options,
isHelp: args.h
}
})
直接看这里可能有点懵, 但是前面看到是kernel注册了 create.js 的, 所以剩下的执行是到 presets/commands/create.ts了
const type = options.type || createTemplateTypeEnum.PAGE
这里也解释了 为什么我们不带 --type 默认给我们创建了page
创建了一个page对象, 然后调用他的create()方法
在 ./src/create/page.ts中
看到这里一个核心的内容是
export const MODIFY_CREATE_TEMPLATE = 'modifyCreateTemplate'
还有就是 args 只有这些内容
{
pageName: name,
projectDir: appPath,
description,
framework: ctx.initialConfig.framework,
async modifyCustomTemplateConfig (cb: TSetCustomTemplateConfig) {
await ctx.applyPlugins({ name: hooks.MODIFY_CREATE_TEMPLATE, opts: cb })
}
}
那么 this.conf.isCustomTemplate 必然为 false
"templateInfo": {
"name": "vue3-pinia",
"typescript": true,
"css": "less"
},
从package.json中读取这个配置
最终看到
getPkgTemplateInfo
"templateInfo": {
"name": "vue3-pinia",
"typescript": true,
"css": "less"
},
templates目录下肯定不存在vue-pinia, 那么就看fetchTemplates() 这个函数了
是从~/.taro3.6/index.json目录下 读取templateSource 这个字段, 得到的地址是
github:NervJS/taro-project-templates#v3.6
然后看下面的 fetch, 最终发现模版在
~/Library/pnpm/global/5/node_modules/@tarojs/cli/templates/vue3-pinia 这个目录下
然后看 template_creator.js 中的
const basePageFiles = [
'/src/pages/index/index.css',
'/src/pages/index/index.vue',
'/src/pages/index/index.config.js'
]
即是我们的代码模版文件, 剩下的就是一些检查
截止到目前, 我们如果想要自定义模版的话, 就是fork一份 github:NervJS/taro-project-templates#v3.6 然后修改下里面的模版就好,
当然这个配置肯定会随着版本升级的变化而变化, 到时也跟着修改就好