@tarojs/cli
Version:
cli tool for taro
397 lines • 15.7 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const helper_1 = require("@tarojs/helper");
const shared_1 = require("@tarojs/shared");
const inquirer = require("inquirer");
const ora = require("ora");
const path = require("path");
const request = require("request");
const semver = require("semver");
const util_1 = require("../util");
const creator_1 = require("./creator");
const fetchTemplate_1 = require("./fetchTemplate");
const init_1 = require("./init");
const NONE_AVAILABLE_TEMPLATE = '无可用模板';
class Project extends creator_1.default {
constructor(options) {
super(options.sourceRoot);
this.askProjectName = function (conf, prompts) {
if ((typeof conf.projectName) !== 'string') {
prompts.push({
type: 'input',
name: 'projectName',
message: '请输入项目名称!',
validate(input) {
if (!input) {
return '项目名不能为空!';
}
if (helper_1.fs.existsSync(input)) {
return '当前目录已经存在同名项目,请换一个项目名!';
}
return true;
}
});
}
else if (helper_1.fs.existsSync(conf.projectName)) {
prompts.push({
type: 'input',
name: 'projectName',
message: '当前目录已经存在同名项目,请换一个项目名!',
validate(input) {
if (!input) {
return '项目名不能为空!';
}
if (helper_1.fs.existsSync(input)) {
return '项目名依然重复!';
}
return true;
}
});
}
};
this.askDescription = function (conf, prompts) {
if (typeof conf.description !== 'string') {
prompts.push({
type: 'input',
name: 'description',
message: '请输入项目介绍'
});
}
};
this.askTypescript = function (conf, prompts) {
if (typeof conf.typescript !== 'boolean') {
prompts.push({
type: 'confirm',
name: 'typescript',
message: '是否需要使用 TypeScript ?'
});
}
};
this.askCSS = function (conf, prompts) {
const cssChoices = [
{
name: 'Sass',
value: 'sass'
},
{
name: 'Less',
value: 'less'
},
{
name: 'Stylus',
value: 'stylus'
},
{
name: '无',
value: 'none'
}
];
if (typeof conf.css !== 'string') {
prompts.push({
type: 'list',
name: 'css',
message: '请选择 CSS 预处理器(Sass/Less/Stylus)',
choices: cssChoices
});
}
};
this.askCompiler = function (conf, prompts) {
const compilerChoices = [
{
name: 'Webpack5',
value: 'webpack5'
},
{
name: 'Webpack4',
value: 'webpack4'
}
];
if (typeof conf.compiler !== 'string') {
prompts.push({
type: 'list',
name: 'compiler',
message: '请选择编译工具',
choices: compilerChoices
});
}
};
this.askFramework = function (conf, prompts) {
const frameworks = [
{
name: 'React',
value: 'react'
},
{
name: 'PReact',
value: 'preact'
},
// {
// name: 'Nerv',
// value: 'nerv'
// },
{
name: 'Vue',
value: 'vue'
},
{
name: 'Vue3',
value: 'vue3'
}
];
if (typeof conf.framework !== 'string') {
prompts.push({
type: 'list',
name: 'framework',
message: '请选择框架',
choices: frameworks
});
}
};
this.askTemplateSource = function (conf, prompts) {
return __awaiter(this, void 0, void 0, function* () {
if (conf.template === 'default' || conf.templateSource)
return;
const homedir = (0, helper_1.getUserHomeDir)();
const taroConfigPath = path.join(homedir, helper_1.TARO_CONFIG_FOLDER);
const taroConfig = path.join(taroConfigPath, helper_1.TARO_BASE_CONFIG);
let localTemplateSource;
// 检查本地配置
if (helper_1.fs.existsSync(taroConfig)) {
// 存在则把模板源读出来
const config = yield helper_1.fs.readJSON(taroConfig);
localTemplateSource = config === null || config === void 0 ? void 0 : config.templateSource;
}
else {
// 不存在则创建配置
yield helper_1.fs.createFile(taroConfig);
yield helper_1.fs.writeJSON(taroConfig, { templateSource: helper_1.DEFAULT_TEMPLATE_SRC });
localTemplateSource = helper_1.DEFAULT_TEMPLATE_SRC;
}
const choices = [
{
name: 'Gitee(最快)',
value: helper_1.DEFAULT_TEMPLATE_SRC_GITEE
},
{
name: 'Github(最新)',
value: helper_1.DEFAULT_TEMPLATE_SRC
},
{
name: 'CLI 内置默认模板',
value: 'default-template'
},
{
name: '自定义',
value: 'self-input'
},
{
name: '社区优质模板源',
value: 'open-source'
}
];
if (localTemplateSource && localTemplateSource !== helper_1.DEFAULT_TEMPLATE_SRC && localTemplateSource !== helper_1.DEFAULT_TEMPLATE_SRC_GITEE) {
choices.unshift({
name: `本地模板源:${localTemplateSource}`,
value: localTemplateSource
});
}
prompts.push({
type: 'list',
name: 'templateSource',
message: '请选择模板源',
choices
}, {
type: 'input',
name: 'templateSource',
message: '请输入模板源!',
askAnswered: true,
when(answers) {
return answers.templateSource === 'self-input';
}
}, {
type: 'list',
name: 'templateSource',
message: '请选择社区模板源',
choices(answers) {
return __awaiter(this, void 0, void 0, function* () {
const choices = yield getOpenSourceTemplates(answers.framework);
return choices;
});
},
askAnswered: true,
when(answers) {
return answers.templateSource === 'open-source';
}
});
});
};
this.askTemplate = function (conf, prompts, list = []) {
const choices = [
{
name: '默认模板',
value: 'default'
},
...list.map(item => ({
name: item.desc ? `${item.name}(${item.desc})` : item.name,
value: item.name
}))
];
if (typeof conf.template !== 'string') {
prompts.push({
type: 'list',
name: 'template',
message: '请选择模板',
choices
});
}
};
this.askNpm = function (conf, prompts) {
const packages = [
{
name: 'yarn',
value: 'yarn'
},
{
name: 'pnpm',
value: 'pnpm'
},
{
name: 'npm',
value: 'npm'
},
{
name: 'cnpm',
value: 'cnpm'
}
];
if (typeof conf.npm !== 'string') {
prompts.push({
type: 'list',
name: 'npm',
message: '请选择包管理工具',
choices: packages
});
}
};
const unSupportedVer = semver.lt(process.version, 'v7.6.0');
if (unSupportedVer) {
throw new Error('Node.js 版本过低,推荐升级 Node.js 至 v8.0.0+');
}
this.rootPath = this._rootPath;
this.conf = Object.assign({
projectName: '',
projectDir: '',
template: '',
description: '',
npm: ''
}, options);
}
init() {
(0, util_1.clearConsole)();
console.log(helper_1.chalk.green('Taro 即将创建一个新项目!'));
console.log(`Need help? Go and open issue: ${helper_1.chalk.blueBright('https://tls.jd.com/taro-issue-helper')}`);
console.log();
}
create() {
return __awaiter(this, void 0, void 0, function* () {
try {
const answers = yield this.ask();
const date = new Date();
this.conf = Object.assign(this.conf, answers);
this.conf.date = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
this.write();
}
catch (error) {
console.log(helper_1.chalk.red('创建项目失败: ', error));
}
});
}
ask() {
return __awaiter(this, void 0, void 0, function* () {
let prompts = [];
const conf = this.conf;
this.askProjectName(conf, prompts);
this.askDescription(conf, prompts);
this.askFramework(conf, prompts);
this.askTypescript(conf, prompts);
this.askCSS(conf, prompts);
this.askCompiler(conf, prompts);
this.askNpm(conf, prompts);
yield this.askTemplateSource(conf, prompts);
const answers = yield inquirer.prompt(prompts);
prompts = [];
const templates = yield this.fetchTemplates(answers);
yield this.askTemplate(conf, prompts, templates);
const templateChoiceAnswer = yield inquirer.prompt(prompts);
return Object.assign(Object.assign({}, answers), templateChoiceAnswer);
});
}
fetchTemplates(answers) {
return __awaiter(this, void 0, void 0, function* () {
const { templateSource, framework } = answers;
this.conf.templateSource = this.conf.templateSource || templateSource;
// 使用默认模版
if (answers.templateSource === 'default-template') {
this.conf.template = 'default';
answers.templateSource = helper_1.DEFAULT_TEMPLATE_SRC_GITEE;
}
if (this.conf.template === 'default' || answers.templateSource === NONE_AVAILABLE_TEMPLATE)
return Promise.resolve([]);
// 从模板源下载模板
const isClone = /gitee/.test(this.conf.templateSource) || this.conf.clone;
const templateChoices = yield (0, fetchTemplate_1.default)(this.conf.templateSource, this.templatePath(''), isClone);
// 根据用户选择的框架筛选模板
const newTemplateChoices = templateChoices
.filter(templateChoice => {
var _a;
const { platforms } = templateChoice;
if (typeof platforms === 'string' && platforms) {
return framework === templateChoice.platforms;
}
else if ((0, shared_1.isArray)(platforms)) {
return (_a = templateChoice.platforms) === null || _a === void 0 ? void 0 : _a.includes(framework);
}
else {
return true;
}
});
return newTemplateChoices;
});
}
write(cb) {
this.conf.src = helper_1.SOURCE_DIR;
(0, init_1.createApp)(this, this.conf, cb).catch(err => console.log(err));
}
}
exports.default = Project;
function getOpenSourceTemplates(platform) {
return new Promise((resolve, reject) => {
const spinner = ora({ text: '正在拉取开源模板列表...', discardStdin: false }).start();
request.get('https://gitee.com/NervJS/awesome-taro/raw/next/index.json', (error, _response, body) => {
if (error) {
spinner.fail(helper_1.chalk.red('拉取开源模板列表失败!'));
return reject(new Error());
}
spinner.succeed(`${helper_1.chalk.grey('拉取开源模板列表成功!')}`);
const collection = JSON.parse(body);
switch (platform) {
case 'react':
return resolve(collection.react);
case 'vue':
return resolve(collection.vue);
default:
return resolve([NONE_AVAILABLE_TEMPLATE]);
}
});
});
}
//# sourceMappingURL=project.js.map