@lcap/builder
Version:
lcap builder utils
242 lines (241 loc) • 11 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.generateComponentFile = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const lodash_1 = require("lodash");
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const fs_1 = require("../utils/fs");
function generateElementUIComponent(context) {
const withFormName = (0, utils_1.addPrefix)((0, utils_1.getWithFormName)(context.naslUIConfig.name), context.prefix);
const withFormTagName = (0, lodash_1.kebabCase)(withFormName);
const vueCode = [
'<template>',
' <base-component />',
'</template>',
'<script>',
...(context.naslUIConfig.sourceDocURL
? ['/**', ` * 组件文档地址: ${context.naslUIConfig.sourceDocURL}`, ' */']
: []),
context.isWithForm
? `import { BaseComponent, lowCodeFormFieldMixin } from '${constants_1.LCAP_UI_PACKAGE_NAME}';`
: `import { BaseComponent } from '${constants_1.LCAP_UI_PACKAGE_NAME}';`,
'',
'export default {',
` name: '${context.tagName}',`,
' inheritAttrs: false,',
...(context.isWithForm ? [` mixins: [lowCodeFormFieldMixin('${context.tagName}', '${withFormTagName}')],`] : []),
' components: {',
' BaseComponent,',
' },',
'};',
'</script>',
'<style>',
'</style>',
'',
].join('\n');
const indexCode = [
`import { extendComponent,${context.isWithForm ? ' WithFormItem,' : ''} ${context.naslUIConfig.name} } from '${constants_1.LCAP_UI_PACKAGE_NAME}';`,
`import Extend${context.naslUIConfig.name} from './index.vue';`,
'',
`export const ${context.name} = extendComponent(${context.naslUIConfig.name}, Extend${context.naslUIConfig.name});`,
...(context.isWithForm
? [
`export const ${withFormName} = WithFormItem(${context.name}, { name: '${withFormTagName}', methodNames: [${context.naslUIConfig.methods
.map((m) => `'${m.name}'`)
.join(', ')}] });`,
]
: []),
`export default ${context.name};`,
'',
].join('\n');
fs_extra_1.default.writeFileSync(path_1.default.resolve(context.componentFolderPath, 'index.vue'), vueCode, 'utf-8');
fs_extra_1.default.writeFileSync(path_1.default.resolve(context.componentFolderPath, 'index.ts'), indexCode, 'utf-8');
}
function generateVueComponent(context) {
return __awaiter(this, void 0, void 0, function* () {
if (context.libInfo.name === '@lcap/element-ui') {
generateElementUIComponent(context);
return;
}
const slotCodes = context.naslUIConfig.slots.map((slot) => {
return ` <slot name="${slot.name}" slot="${slot.name}"></slot>`;
});
const methodCodes = context.naslUIConfig.methods.map((m) => {
return [` ${m.name}(...args) {`, ` this.$refs.base.${m.name}(...args)`, ' },'].join('\n');
});
const templateCodes = [
`<${context.naslUIConfig.kebabName} ref="base" class="${context.tagName}" v-bind="$attrs" v-on="$listeners">`,
`</${context.naslUIConfig.kebabName}>`,
];
if (slotCodes.length > 0) {
templateCodes.splice(1, 0, slotCodes.join('\n'));
}
const code = [
'<template>',
...templateCodes,
'</template>',
'<script>',
'export default {',
` name: '${context.tagName}',`,
...(methodCodes.length > 0 ? [' methods: {', ...methodCodes, ' }'] : []),
'};',
'</script>',
'<style>',
`.${context.tagName}{`,
'}',
'</style>',
'',
].join('\n');
fs_extra_1.default.writeFileSync(path_1.default.resolve(context.componentFolderPath, 'index.vue'), code, 'utf-8');
});
}
function generateReactComponent(context) {
return __awaiter(this, void 0, void 0, function* () {
const code = [
"import React, { forwardRef } from 'react'",
`import { ${context.naslUIConfig.name} } from '${constants_1.LCAP_UI_PACKAGE_NAME}'`,
'',
`const ${context.name} = forwardRef<any, any>((props, ref) => {`,
' const {',
' ...rest',
' } = props;',
'',
' return (',
` <${context.naslUIConfig.name}`,
' ref={ref}',
' {...rest}',
' />',
' );',
'});',
'',
`export default ${context.name}`,
'',
].join('\n');
fs_extra_1.default.writeFileSync(path_1.default.resolve(context.componentFolderPath, 'index.tsx'), code, 'utf-8');
});
}
function generateElementPlusComponent(context) {
return __awaiter(this, void 0, void 0, function* () {
const withFormName = (0, utils_1.addPrefix)((0, utils_1.getWithFormName)(context.naslUIConfig.name), context.prefix);
const withFormTagName = (0, lodash_1.kebabCase)(withFormName);
const componentFileName = `${context.name}.tsx`;
const indexCode = [
`import ${context.name} from './${componentFileName}';`,
...(context.isWithForm
? [
`import { withFormItem } from '${constants_1.LCAP_UI_PACKAGE_NAME}';`,
'',
`export const ${withFormName} = withFormItem(${context.name}, '${withFormTagName}');`,
]
: []),
'',
'export {',
` ${context.name},`,
'};',
'',
`export default ${context.name};`,
'',
].join('\n');
const BaseComponentName = `${context.naslUIConfig.name}Plus`;
const RegisterFunctionName = `${context.naslUIConfig.name}Register`;
const componentCode = [
'import { defineComponent, ref } from \'vue\';',
`import { ${BaseComponentName} as ${context.naslUIConfig.name}, ${RegisterFunctionName} as registerComponent } from '${constants_1.LCAP_UI_PACKAGE_NAME}';`,
'',
`const ${context.name} = defineComponent({`,
` name: '${context.naslUIConfig.name}Extend',`,
' setup(props, { attrs, slots, expose }) {',
' const componentRef = ref(null);',
'',
' expose({',
' componentRef,',
' });',
'',
' return () => {',
' return (',
` <${context.naslUIConfig.name}`,
' {...props}',
' {...attrs}',
' v-slots={slots}',
' ref={componentRef}',
' />',
' );',
' };',
' },',
'});',
'',
`export default registerComponent(${context.name}, { name: '${context.tagName}' });`,
].join('\n');
const indexVuePath = path_1.default.resolve(context.componentFolderPath, 'index.vue');
if (fs_extra_1.default.existsSync(indexVuePath)) {
fs_extra_1.default.rmSync(indexVuePath); // 删除 vue 文件
}
fs_extra_1.default.writeFileSync(path_1.default.resolve(context.componentFolderPath, 'index.ts'), indexCode, 'utf-8');
fs_extra_1.default.writeFileSync(path_1.default.resolve(context.componentFolderPath, componentFileName), componentCode, 'utf-8');
});
}
// 添加 index.ts 中的子组件 exports
function addIndexExports(context) {
const indexPath = (0, fs_1.getPath)(path_1.default.resolve(context.componentFolderPath, './index'));
if (!indexPath || !fs_extra_1.default.existsSync(indexPath)) {
return;
}
const needExportNames = context.replaceNames.filter((name) => {
const exportName = context.replaceNameMap[name];
return exportName && exportName !== context.name && (!context.isWithForm || name !== context.withFormName);
});
if (needExportNames.length === 0) {
return;
}
const codes = fs_extra_1.default.readFileSync(indexPath, 'utf-8').split('\n');
codes.push(`import { ${needExportNames
.map((n) => `${n} as ${context.replaceNameMap[n]}`)
.join(', ')} } from '${constants_1.LCAP_UI_PACKAGE_NAME}';`);
codes.push(`export { ${needExportNames.map((n) => context.replaceNameMap[n]).join(', ')} };\n`);
fs_extra_1.default.writeFileSync(indexPath, codes.join('\n'), 'utf-8');
}
function addComponentsExports(context) {
const indexPath = path_1.default.resolve(context.componentFolderPath, '../index.ts');
const needExportNames = context.exportNames.filter((name) => name !== context.name);
if (!fs_extra_1.default.existsSync(indexPath) || needExportNames.length === 0) {
return;
}
const folderName = path_1.default.basename(context.componentFolderPath);
const codes = fs_extra_1.default.readFileSync(indexPath, 'utf-8').split('\n');
codes.push(`export { ${needExportNames.join(', ')} } from './${folderName}';\n`);
fs_extra_1.default.writeFileSync(indexPath, codes.join('\n'), 'utf-8');
}
function generateComponentFile(context) {
return __awaiter(this, void 0, void 0, function* () {
switch (true) {
case context.framework === 'vue2':
yield generateVueComponent(context);
break;
case context.framework === 'react':
yield generateReactComponent(context);
break;
case context.framework === 'vue3' && context.libInfo.name === '@lcap/element-plus':
yield generateElementPlusComponent(context);
break;
default:
break;
}
addIndexExports(context);
addComponentsExports(context);
});
}
exports.generateComponentFile = generateComponentFile;