Skip to content

Commit c12054b

Browse files
authored
feat(cli): 支持更改 CLI 展示的模板名称 (#15940)
1 parent a8ac196 commit c12054b

File tree

4 files changed

+1357
-1314
lines changed

4 files changed

+1357
-1314
lines changed

packages/taro-cli/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@
4444
"dependencies": {
4545
"@tarojs/binding": "workspace:*",
4646
"@tarojs/helper": "workspace:*",
47+
"@tarojs/plugin-doctor": "^0.0.11",
4748
"@tarojs/service": "workspace:*",
4849
"@tarojs/shared": "workspace:*",
49-
"@tarojs/plugin-doctor": "^0.0.11",
5050
"adm-zip": "^0.4.13",
51+
"axios": "^1.6.8",
5152
"cli-highlight": "^2.1.11",
5253
"download-git-repo": "^2.0.0",
5354
"envinfo": "^7.8.1",

packages/taro-cli/src/create/fetchTemplate.ts

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import { chalk, fs } from '@tarojs/helper'
22
import * as AdmZip from 'adm-zip'
3+
import axios from 'axios'
34
import * as download from 'download-git-repo'
45
import * as ora from 'ora'
56
import * as path from 'path'
6-
import * as request from 'request'
77

88
import { getTemplateSourceType, readDirWithFileTypes } from '../util'
99
import { TEMPLATE_CREATOR } from './constants'
1010

1111
export interface ITemplates {
1212
name: string
13+
value: string
1314
platforms?: string | string[]
1415
desc?: string
16+
compiler?: string[]
1517
}
1618

1719
const TEMP_DOWNLOAD_FOLDER = 'taro-temp'
@@ -20,8 +22,6 @@ export default function fetchTemplate (templateSource: string, templateRootPath:
2022
const type = getTemplateSourceType(templateSource)
2123
const tempPath = path.join(templateRootPath, TEMP_DOWNLOAD_FOLDER)
2224
let name: string
23-
let isFromUrl = false
24-
2525
// eslint-disable-next-line no-async-promise-executor
2626
return new Promise<void>(async (resolve) => {
2727
// 下载文件的缓存目录
@@ -47,23 +47,36 @@ export default function fetchTemplate (templateSource: string, templateRootPath:
4747
} else if (type === 'url') {
4848
// url 模板源,因为不知道来源名称,临时取名方便后续开发者从列表中选择
4949
name = 'from-remote-url'
50-
isFromUrl = true
5150
const zipPath = path.join(tempPath, name + '.zip')
52-
request
53-
.get(templateSource)
54-
.pipe(fs.createWriteStream(zipPath))
55-
.on('close', () => {
56-
// unzip
57-
const zip = new AdmZip(zipPath)
58-
zip.extractAllTo(path.join(tempPath, name), true)
59-
60-
spinner.color = 'green'
61-
spinner.succeed(`${chalk.grey('拉取远程模板仓库成功!')}`)
62-
resolve()
51+
const unZipPath = path.join(tempPath, name)
52+
axios.get<fs.ReadStream>(templateSource, { responseType: 'stream' })
53+
.then(response => {
54+
const ws = fs.createWriteStream(zipPath)
55+
response.data.pipe(ws)
56+
ws.on('finish', () => {
57+
// unzip
58+
const zip = new AdmZip(zipPath)
59+
zip.extractAllTo(unZipPath, true)
60+
const files = readDirWithFileTypes(unZipPath).filter(
61+
file => !file.name.startsWith('.') && file.isDirectory && file.name !== '__MACOSX'
62+
)
63+
64+
if (files.length !== 1) {
65+
spinner.color = 'red'
66+
spinner.fail(chalk.red(`拉取远程模板仓库失败!\n${new Error('远程模板源组织格式错误')}`))
67+
return resolve()
68+
}
69+
name = path.join(name, files[0].name)
70+
71+
spinner.color = 'green'
72+
spinner.succeed(`${chalk.grey('拉取远程模板仓库成功!')}`)
73+
resolve()
74+
})
75+
ws.on('error', error => { throw error })
6376
})
64-
.on('error', async err => {
77+
.catch(async error => {
6578
spinner.color = 'red'
66-
spinner.fail(chalk.red(`拉取远程模板仓库失败!\n${err}`))
79+
spinner.fail(chalk.red(`拉取远程模板仓库失败!\n${error}`))
6780
await fs.remove(tempPath)
6881
return resolve()
6982
})
@@ -96,13 +109,14 @@ export default function fetchTemplate (templateSource: string, templateRootPath:
96109
const res: ITemplates[] = files.map(name => {
97110
const creatorFile = path.join(templateRootPath, name, TEMPLATE_CREATOR)
98111

99-
if (!fs.existsSync(creatorFile)) return { name }
100-
101-
const { platforms = '', desc = '' } = require(creatorFile)
112+
if (!fs.existsSync(creatorFile)) return { name, value: name }
113+
const { name: displayName, platforms = '', desc = '', compiler } = require(creatorFile)
102114

103115
return {
104-
name,
116+
name: displayName || name,
117+
value: name,
105118
platforms,
119+
compiler,
106120
desc
107121
}
108122
})
@@ -112,15 +126,18 @@ export default function fetchTemplate (templateSource: string, templateRootPath:
112126
await fs.move(templateFolder, path.join(templateRootPath, name), { overwrite: true })
113127
await fs.remove(tempPath)
114128

115-
let res: ITemplates = { name, desc: isFromUrl ? templateSource : '' }
129+
let res: ITemplates = { name, value: name, desc: type === 'url' ? templateSource : '' }
130+
116131
const creatorFile = path.join(templateRootPath, name, TEMPLATE_CREATOR)
117132

118133
if (fs.existsSync(creatorFile)) {
119-
const { platforms = '', desc = '' } = require(creatorFile)
134+
const { name: displayName, platforms = '', desc = '', compiler } = require(creatorFile)
120135

121136
res = {
122-
name,
137+
name: displayName || name,
138+
value: name,
123139
platforms,
140+
compiler,
124141
desc: desc || templateSource
125142
}
126143
}

packages/taro-cli/src/create/project.ts

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import {
1010
TARO_CONFIG_FOLDER
1111
} from '@tarojs/helper'
1212
import { isArray } from '@tarojs/shared'
13+
import axios from 'axios'
1314
import * as inquirer from 'inquirer'
1415
import * as ora from 'ora'
1516
import * as path from 'path'
16-
import * as request from 'request'
1717
import * as semver from 'semver'
1818

1919
import { clearConsole, getPkgVersion, getRootPath } from '../util'
@@ -38,6 +38,7 @@ export interface IProjectConf {
3838
sourceRoot?: string
3939
env?: string
4040
autoInstall?: boolean
41+
hideDefaultTemplate?: boolean
4142
framework: FrameworkType
4243
compiler?: CompilerType
4344
}
@@ -58,9 +59,9 @@ export default class Project extends Creator {
5859

5960
constructor (options: IProjectConfOptions) {
6061
super(options.sourceRoot)
61-
const unSupportedVer = semver.lt(process.version, 'v7.6.0')
62+
const unSupportedVer = semver.lt(process.version, 'v18.0.0')
6263
if (unSupportedVer) {
63-
throw new Error('Node.js 版本过低,推荐升级 Node.js 至 v8.0.0+')
64+
throw new Error('Node.js 版本过低,推荐升级 Node.js 至 v18.0.0+')
6465
}
6566
this.rootPath = this._rootPath
6667

@@ -341,16 +342,17 @@ export default class Project extends Creator {
341342
}
342343

343344
askTemplate: AskMethods = function (conf, prompts, list = []) {
344-
const choices = [
345-
{
345+
const choices = list.map(item => ({
346+
name: item.desc ? `${item.name}${item.desc})` : item.name,
347+
value: item.value || item.name
348+
}))
349+
350+
if (!conf.hideDefaultTemplate) {
351+
choices.unshift({
346352
name: '默认模板',
347353
value: 'default'
348-
},
349-
...list.map(item => ({
350-
name: item.desc ? `${item.name}${item.desc})` : item.name,
351-
value: item.name
352-
}))
353-
]
354+
})
355+
}
354356

355357
if ((typeof conf.template as 'string' | undefined) !== 'string') {
356358
prompts.push({
@@ -393,7 +395,8 @@ export default class Project extends Creator {
393395
}
394396

395397
async fetchTemplates (answers: IProjectConf): Promise<ITemplates[]> {
396-
const { templateSource, framework } = answers
398+
const { templateSource, framework, compiler } = answers
399+
this.conf.framework = this.conf.framework || framework || ''
397400
this.conf.templateSource = this.conf.templateSource || templateSource
398401

399402
// 使用默认模版
@@ -407,17 +410,30 @@ export default class Project extends Creator {
407410
const isClone = /gitee/.test(this.conf.templateSource) || this.conf.clone
408411
const templateChoices = await fetchTemplate(this.conf.templateSource, this.templatePath(''), isClone)
409412

413+
const filterFramework = (_framework) => {
414+
const current = this.conf.framework?.toLowerCase()
415+
416+
if (typeof _framework === 'string' && _framework) {
417+
return current === _framework.toLowerCase()
418+
} else if (isArray(_framework)) {
419+
return _framework?.map(name => name.toLowerCase()).includes(current)
420+
} else {
421+
return true
422+
}
423+
}
424+
425+
const filterCompiler = (_compiler) => {
426+
if (_compiler && isArray(_compiler)) {
427+
return _compiler?.includes(compiler)
428+
}
429+
return true
430+
}
431+
410432
// 根据用户选择的框架筛选模板
411433
const newTemplateChoices: ITemplates[] = templateChoices
412434
.filter(templateChoice => {
413-
const { platforms } = templateChoice
414-
if (typeof platforms === 'string' && platforms) {
415-
return framework === templateChoice.platforms
416-
} else if (isArray(platforms)) {
417-
return templateChoice.platforms?.includes(framework)
418-
} else {
419-
return true
420-
}
435+
const { platforms, compiler } = templateChoice
436+
return filterFramework(platforms) && filterCompiler(compiler)
421437
})
422438

423439
return newTemplateChoices
@@ -451,27 +467,23 @@ export default class Project extends Creator {
451467
}
452468
}
453469

454-
function getOpenSourceTemplates (platform) {
470+
function getOpenSourceTemplates (platform: string) {
455471
return new Promise((resolve, reject) => {
456472
const spinner = ora({ text: '正在拉取开源模板列表...', discardStdin: false }).start()
457-
request.get('https://gitee.com/NervJS/awesome-taro/raw/next/index.json', (error, _response, body) => {
458-
if (error) {
473+
axios.get('https://gitee.com/NervJS/awesome-taro/raw/next/index.json')
474+
.then(response => {
475+
spinner.succeed(`${chalk.grey('拉取开源模板列表成功!')}`)
476+
const collection = response.data
477+
switch (platform.toLowerCase()) {
478+
case 'react':
479+
return resolve(collection.react)
480+
default:
481+
return resolve([NONE_AVAILABLE_TEMPLATE])
482+
}
483+
})
484+
.catch(_error => {
459485
spinner.fail(chalk.red('拉取开源模板列表失败!'))
460486
return reject(new Error())
461-
}
462-
463-
spinner.succeed(`${chalk.grey('拉取开源模板列表成功!')}`)
464-
465-
const collection = JSON.parse(body)
466-
467-
switch (platform) {
468-
case 'react':
469-
return resolve(collection.react)
470-
case 'vue':
471-
return resolve(collection.vue)
472-
default:
473-
return resolve([NONE_AVAILABLE_TEMPLATE])
474-
}
475-
})
487+
})
476488
})
477489
}

0 commit comments

Comments
 (0)