@lcap/builder
Version:
lcap builder utils
228 lines (227 loc) • 10.2 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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeCreateComponent = exports.createComponent = exports.getTagName = exports.getCreateComponentOptions = exports.COMPONENTS_FOLDER = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const picocolors_1 = __importDefault(require("picocolors"));
const prompts_1 = __importDefault(require("prompts"));
const lodash_1 = require("lodash");
const project_1 = require("../utils/project");
const fs_1 = require("../utils/fs");
const logger_1 = __importDefault(require("../utils/logger"));
const overload_1 = __importDefault(require("../commands/overload"));
exports.COMPONENTS_FOLDER = 'src/components';
function isSupportFork(metaInfo) {
if (metaInfo.framework !== 'vue2') {
return false;
}
if (metaInfo.libUIInfo && metaInfo.libUIInfo.pkgName === '@lcap/element-ui') {
return false;
}
return true;
}
function getCreateComponentOptions(rootPath, metaInfo) {
return __awaiter(this, void 0, void 0, function* () {
const componentList = (0, project_1.getComponentList)(rootPath);
let result = {
name: '',
title: '',
type: 'pc',
overload: false,
};
let createMode = 'create';
try {
if (componentList.length > 0) {
const createModeAnswers = yield (0, prompts_1.default)([
{
type: 'select',
name: 'createMode',
message: '请选择创建组件方式',
initial: 0,
choices: [
{ value: 'create', title: '添加新组件' },
{ value: 'overload', title: '重载基础组件' },
],
},
], {
onCancel: () => {
// eslint-disable-next-line prefer-template
throw new Error(picocolors_1.default.red('✖') + ' 已取消');
},
});
createMode = createModeAnswers.createMode;
}
if (createMode === 'overload') {
const supportFork = isSupportFork(metaInfo);
const overloadAnswers = yield (0, prompts_1.default)([
{
type: 'select',
name: 'baseComponentName',
message: '请选择重载的基础组件',
initial: 0,
choices: componentList.map((c) => ({ value: c.name, title: `${c.name}(${c.title})` })),
},
{
type: 'text',
name: 'prefix',
message: '请输入重载名称前缀(例如 ex):',
initial: 'ex',
format: (val) => {
if (!val) {
return 'ex';
}
return val.trim().toLowerCase();
},
},
{
type: () => (supportFork ? 'confirm' : null),
name: 'fork',
message: '是否复制基础组件源代码?\n复制组件源码后,该组件将完全独立,无法继续跟随基础组件能力升级变化,请慎重处理;',
initial: true,
},
]);
const comp = componentList.find((it) => it.name === overloadAnswers.baseComponentName);
result = Object.assign(Object.assign(Object.assign({}, result), overloadAnswers), { fork: supportFork && overloadAnswers.fork, name: (0, lodash_1.upperFirst)(overloadAnswers.prefix) + overloadAnswers.baseComponentName, title: comp ? comp.title : '', type: metaInfo.libUIInfo && metaInfo.libUIInfo.type ? metaInfo.libUIInfo.type : 'pc', overload: true });
}
else {
const createAnswers = yield (0, prompts_1.default)([
{
type: 'text',
name: 'name',
message: '请输入组件名字(使用大驼峰方式命名,例如:TreeSelect)',
format: (val) => (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(val).trim()),
validate: (v) => {
if (!v || v.trim === '') {
return '组件名字不能为空';
}
return true;
},
},
{
type: 'text',
name: 'title',
message: '请输入别名(中文名),例如:树形选择器',
validate: (v) => {
if (!v || v.trim === '') {
return '别名不能为空';
}
return true;
},
},
{
type: metaInfo.framework === 'react' ? null : 'select',
name: 'type',
message: '请选择端',
initial: 0,
choices: [
{ value: 'pc', title: 'PC端' },
{ value: 'h5', title: 'H5端' },
{ value: 'both', title: '全部' },
],
},
], {
onCancel: () => {
// eslint-disable-next-line prefer-template
throw new Error(picocolors_1.default.red('✖') + ' 已取消');
},
});
result = Object.assign(Object.assign(Object.assign({}, result), createAnswers), { overload: false });
}
}
catch (cancelled) {
console.log(cancelled.message);
return null;
}
return result;
});
}
exports.getCreateComponentOptions = getCreateComponentOptions;
function getTagName(framework, name) {
return framework.startsWith('vue') ? (0, lodash_1.kebabCase)(name) : name;
}
exports.getTagName = getTagName;
function createComponent(rootPath, metaInfo, options) {
const templateFolder = path_1.default.resolve(__dirname, '../../templates', `${metaInfo.framework}-component`);
if (!fs_extra_1.default.existsSync(templateFolder)) {
throw new Error(`未找到 ${metaInfo.framework} 组件模板`);
}
const compName = (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(options.name));
const tagName = getTagName(metaInfo.framework, compName);
const componentFolder = path_1.default.resolve(rootPath, exports.COMPONENTS_FOLDER, tagName);
if (fs_extra_1.default.existsSync(componentFolder)) {
throw new Error(`组件目录 ${componentFolder} 已存在`);
}
const replaceTextList = [
{
reg: /\{\{pkgName\}\}/g,
text: metaInfo.name,
},
{
reg: /\{\{tagName\}\}/g,
text: tagName,
},
{
reg: /\{\{compName\}\}/g,
text: compName,
},
{
reg: /\{\{title\}\}/g,
text: options.title,
},
{
reg: /\{\{description\}\}/g,
text: options.title,
},
{
reg: /\{\{type\}\}/g,
text: options.type,
},
];
(0, fs_1.copy)(templateFolder, componentFolder, replaceTextList);
const componentIndexPath = path_1.default.resolve(rootPath, exports.COMPONENTS_FOLDER, 'index.ts');
if (!fs_extra_1.default.existsSync(componentIndexPath)) {
return;
}
// 写入 import
const content = fs_extra_1.default.readFileSync(componentIndexPath, 'utf-8').toString();
fs_extra_1.default.writeFileSync(componentIndexPath, [
...content
.toString()
.split('\n')
.filter((c) => !!c.trim()),
`export { default as ${compName} } from './${tagName}';`,
'',
].join('\n'), 'utf-8');
}
exports.createComponent = createComponent;
function executeCreateComponent(rootPath, metaInfo, prompt) {
return __awaiter(this, void 0, void 0, function* () {
const options = prompt !== null && prompt !== void 0 ? prompt : yield getCreateComponentOptions(rootPath, metaInfo);
if (!options) {
return;
}
logger_1.default.start(`开始创建组件 ${options.name} ......`);
yield createComponent(rootPath, metaInfo, options);
if (options.overload) {
yield (0, overload_1.default)(rootPath, {
fork: options.fork,
component: options.baseComponentName,
prefix: options.prefix,
});
}
logger_1.default.success(`创建组件成功 ${options.name} !`);
});
}
exports.executeCreateComponent = executeCreateComponent;