mirror of
				https://github.com/Tencent/tmagic-editor.git
				synced 2025-11-04 18:52:18 +08:00 
			
		
		
		
	feat(cli): 如果识别不要组件文件,则默认从npm包的default导入
This commit is contained in:
		
							parent
							
								
									f17ef325b1
								
							
						
					
					
						commit
						b715a87f40
					
				@ -11,11 +11,14 @@ export default class Core {
 | 
			
		||||
  public options: UserConfig;
 | 
			
		||||
 | 
			
		||||
  public moduleMainFilePath: ModuleMainFilePath = {
 | 
			
		||||
    componentPackage: {},
 | 
			
		||||
    componentMap: {},
 | 
			
		||||
    pluginPakcage: {},
 | 
			
		||||
    pluginMap: {},
 | 
			
		||||
    configMap: {},
 | 
			
		||||
    valueMap: {},
 | 
			
		||||
    eventMap: {},
 | 
			
		||||
    datasourcePackage: {},
 | 
			
		||||
    datasourceMap: {},
 | 
			
		||||
    dsConfigMap: {},
 | 
			
		||||
    dsValueMap: {},
 | 
			
		||||
 | 
			
		||||
@ -54,11 +54,14 @@ export interface NpmConfig {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ModuleMainFilePath {
 | 
			
		||||
  componentPackage: Record<string, string>;
 | 
			
		||||
  componentMap: Record<string, string>;
 | 
			
		||||
  pluginPakcage: Record<string, string>;
 | 
			
		||||
  pluginMap: Record<string, string>;
 | 
			
		||||
  configMap: Record<string, string>;
 | 
			
		||||
  valueMap: Record<string, string>;
 | 
			
		||||
  eventMap: Record<string, string>;
 | 
			
		||||
  datasourcePackage: Record<string, string>;
 | 
			
		||||
  datasourceMap: Record<string, string>;
 | 
			
		||||
  dsConfigMap: Record<string, string>;
 | 
			
		||||
  dsValueMap: Record<string, string>;
 | 
			
		||||
 | 
			
		||||
@ -5,33 +5,84 @@ import { EntryType } from '../types';
 | 
			
		||||
 | 
			
		||||
export const prepareEntryFile = async (app: App) => {
 | 
			
		||||
  const { moduleMainFilePath, options } = app;
 | 
			
		||||
  const { componentFileAffix, dynamicImport, hooks, useTs = true } = options;
 | 
			
		||||
  const { dynamicImport, hooks, useTs = true } = options;
 | 
			
		||||
 | 
			
		||||
  let contentMap: Record<string, string> = {
 | 
			
		||||
    'comp-entry': generateContent(useTs, EntryType.COMPONENT, moduleMainFilePath.componentMap, componentFileAffix),
 | 
			
		||||
    'comp-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.COMPONENT,
 | 
			
		||||
      moduleMainFilePath.componentPackage,
 | 
			
		||||
      moduleMainFilePath.componentMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'async-comp-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.COMPONENT,
 | 
			
		||||
      moduleMainFilePath.componentPackage,
 | 
			
		||||
      moduleMainFilePath.componentMap,
 | 
			
		||||
      componentFileAffix,
 | 
			
		||||
      dynamicImport,
 | 
			
		||||
    ),
 | 
			
		||||
    'plugin-entry': generateContent(useTs, EntryType.PLUGIN, moduleMainFilePath.pluginMap),
 | 
			
		||||
    'async-plugin-entry': generateContent(useTs, EntryType.PLUGIN, moduleMainFilePath.pluginMap, '', dynamicImport),
 | 
			
		||||
    'config-entry': generateContent(useTs, EntryType.CONFIG, moduleMainFilePath.configMap),
 | 
			
		||||
    'value-entry': generateContent(useTs, EntryType.VALUE, moduleMainFilePath.valueMap),
 | 
			
		||||
    'event-entry': generateContent(useTs, EntryType.EVENT, moduleMainFilePath.eventMap),
 | 
			
		||||
    'datasource-entry': generateContent(useTs, EntryType.DATASOURCE, moduleMainFilePath.datasourceMap),
 | 
			
		||||
    'plugin-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.PLUGIN,
 | 
			
		||||
      moduleMainFilePath.pluginPakcage,
 | 
			
		||||
      moduleMainFilePath.pluginMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'async-plugin-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.PLUGIN,
 | 
			
		||||
      moduleMainFilePath.pluginPakcage,
 | 
			
		||||
      moduleMainFilePath.pluginMap,
 | 
			
		||||
      dynamicImport,
 | 
			
		||||
    ),
 | 
			
		||||
    'config-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.CONFIG,
 | 
			
		||||
      moduleMainFilePath.componentPackage,
 | 
			
		||||
      moduleMainFilePath.configMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'value-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.VALUE,
 | 
			
		||||
      moduleMainFilePath.componentPackage,
 | 
			
		||||
      moduleMainFilePath.valueMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'event-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.EVENT,
 | 
			
		||||
      moduleMainFilePath.componentPackage,
 | 
			
		||||
      moduleMainFilePath.eventMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'datasource-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.DATASOURCE,
 | 
			
		||||
      moduleMainFilePath.datasourcePackage,
 | 
			
		||||
      moduleMainFilePath.datasourceMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'async-datasource-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.DATASOURCE,
 | 
			
		||||
      moduleMainFilePath.datasourcePackage,
 | 
			
		||||
      moduleMainFilePath.datasourceMap,
 | 
			
		||||
      '',
 | 
			
		||||
      dynamicImport,
 | 
			
		||||
    ),
 | 
			
		||||
    'ds-config-entry': generateContent(useTs, EntryType.DS_CONFIG, moduleMainFilePath.dsConfigMap),
 | 
			
		||||
    'ds-value-entry': generateContent(useTs, EntryType.DS_VALUE, moduleMainFilePath.dsValueMap),
 | 
			
		||||
    'ds-event-entry': generateContent(useTs, EntryType.DS_EVENT, moduleMainFilePath.dsEventMap),
 | 
			
		||||
    'ds-config-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.DS_CONFIG,
 | 
			
		||||
      moduleMainFilePath.datasourcePackage,
 | 
			
		||||
      moduleMainFilePath.dsConfigMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'ds-value-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.DS_VALUE,
 | 
			
		||||
      moduleMainFilePath.datasourcePackage,
 | 
			
		||||
      moduleMainFilePath.dsValueMap,
 | 
			
		||||
    ),
 | 
			
		||||
    'ds-event-entry': generateContent(
 | 
			
		||||
      useTs,
 | 
			
		||||
      EntryType.DS_EVENT,
 | 
			
		||||
      moduleMainFilePath.datasourcePackage,
 | 
			
		||||
      moduleMainFilePath.dsEventMap,
 | 
			
		||||
    ),
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (typeof hooks?.beforeWriteEntry === 'function') {
 | 
			
		||||
@ -53,8 +104,8 @@ export const prepareEntryFile = async (app: App) => {
 | 
			
		||||
export const generateContent = (
 | 
			
		||||
  useTs: boolean,
 | 
			
		||||
  type: EntryType,
 | 
			
		||||
  packageMap: Record<string, string> = {},
 | 
			
		||||
  map: Record<string, string> = {},
 | 
			
		||||
  componentFileAffix = '',
 | 
			
		||||
  dynamicImport = false,
 | 
			
		||||
) => {
 | 
			
		||||
  const list: string[] = [];
 | 
			
		||||
@ -62,14 +113,14 @@ export const generateContent = (
 | 
			
		||||
 | 
			
		||||
  Object.entries(map).forEach(([key, packagePath]) => {
 | 
			
		||||
    const name = makeCamelCase(key);
 | 
			
		||||
    if (dynamicImport) {
 | 
			
		||||
      list.push(
 | 
			
		||||
        `'${key}': () => import('${packagePath}${packagePath.endsWith(componentFileAffix) ? '' : componentFileAffix}')`,
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
    if ([EntryType.CONFIG, EntryType.EVENT, EntryType.VALUE].includes(type) && packagePath === packageMap[key]) {
 | 
			
		||||
      importDeclarations.push(`import { ${type} as ${name} } from '${packageMap[key]}'`);
 | 
			
		||||
      list.push(`'${key}': ${name}`);
 | 
			
		||||
    } else if (dynamicImport) {
 | 
			
		||||
      list.push(`'${key}': () => import('${packagePath}')`);
 | 
			
		||||
    } else {
 | 
			
		||||
      importDeclarations.push(
 | 
			
		||||
        `import ${name} from '${packagePath}${packagePath.endsWith(componentFileAffix) ? '' : componentFileAffix}'`,
 | 
			
		||||
      );
 | 
			
		||||
      importDeclarations.push(`import ${name} from '${packagePath}'`);
 | 
			
		||||
      list.push(`'${key}': ${name}`);
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@ -38,20 +38,37 @@ const getRelativePath = (str: string, base: string) => (path.isAbsolute(str) ? p
 | 
			
		||||
 | 
			
		||||
const npmInstall = function (dependencies: Record<string, string>, cwd: string, npmConfig: NpmConfig = {}) {
 | 
			
		||||
  try {
 | 
			
		||||
    const { client = 'npm', registry, installArgs = '' } = npmConfig;
 | 
			
		||||
    const { client = 'npm', registry, installArgs = '', keepPackageJsonClean } = npmConfig;
 | 
			
		||||
    const install = {
 | 
			
		||||
      npm: 'install',
 | 
			
		||||
      yarn: 'add',
 | 
			
		||||
      pnpm: 'add',
 | 
			
		||||
    }[client];
 | 
			
		||||
 | 
			
		||||
    const packages = Object.entries(dependencies)
 | 
			
		||||
      .map(([name, version]) => (version ? `${name}@${version}` : name))
 | 
			
		||||
      .join(' ');
 | 
			
		||||
    let packages = Object.entries(dependencies);
 | 
			
		||||
 | 
			
		||||
    const newPackages = Object.entries(dependencies).filter(([name]) => {
 | 
			
		||||
      if (fs.existsSync(path.resolve(cwd, 'node_modules', name))) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // keepPackageJsonClean会保留原始的package.json,这样配置的packages就不会被写入dependencies中
 | 
			
		||||
    // install 时会删除不在dependencies中的依赖,所以需要install packages中配置的所有包
 | 
			
		||||
    if (!keepPackageJsonClean || !newPackages.length) {
 | 
			
		||||
      packages = newPackages;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!packages.length) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const packageNames = packages.map(([name, version]) => (version ? `${name}@${version}` : name)).join(' ');
 | 
			
		||||
 | 
			
		||||
    const installArgsString = `${installArgs ? ` ${installArgs}` : ''}`;
 | 
			
		||||
    const registryString = `${registry ? ` --registry ${registry}` : ''}`;
 | 
			
		||||
    const command = `${client} ${install}${installArgsString} ${packages}${registryString}`;
 | 
			
		||||
    const command = `${client} ${install}${installArgsString} ${packageNames}${registryString}`;
 | 
			
		||||
 | 
			
		||||
    execInfo(cwd);
 | 
			
		||||
    execInfo(command);
 | 
			
		||||
@ -318,25 +335,30 @@ const parseEntry = function ({ ast, package: module, indexPath }: ParseEntryOpti
 | 
			
		||||
  const tokens = getASTTokenByTraverse({ ast, indexPath });
 | 
			
		||||
  let { config, value, event, component } = tokens;
 | 
			
		||||
 | 
			
		||||
  if (!config) {
 | 
			
		||||
  if (typeof config === 'undefined') {
 | 
			
		||||
    info(`${module} 表单配置文件声明缺失`);
 | 
			
		||||
  }
 | 
			
		||||
  if (!value) {
 | 
			
		||||
  if (typeof value === 'undefined') {
 | 
			
		||||
    info(`${module} 初始化数据文件声明缺失`);
 | 
			
		||||
  }
 | 
			
		||||
  if (!event) {
 | 
			
		||||
  if (typeof event === 'undefined') {
 | 
			
		||||
    info(`${module} 事件声明文件声明缺失`);
 | 
			
		||||
  }
 | 
			
		||||
  if (!component) {
 | 
			
		||||
    info(`${module} 组件或数据源文件声明不合法`);
 | 
			
		||||
    exit(1);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const reg = /^.*[/\\]node_modules[/\\](.*)/;
 | 
			
		||||
  [, config] = config.match(reg) || [, config];
 | 
			
		||||
  [, value] = value.match(reg) || [, value];
 | 
			
		||||
  [, component] = component.match(reg) || [, component];
 | 
			
		||||
  [, event] = event.match(reg) || [, event];
 | 
			
		||||
 | 
			
		||||
  if (config) {
 | 
			
		||||
    [, config] = config.match(reg) || [, config];
 | 
			
		||||
  }
 | 
			
		||||
  if (value) {
 | 
			
		||||
    [, value] = value.match(reg) || [, value];
 | 
			
		||||
  }
 | 
			
		||||
  if (component) {
 | 
			
		||||
    [, component] = component.match(reg) || [, component];
 | 
			
		||||
  }
 | 
			
		||||
  if (event) {
 | 
			
		||||
    [, event] = event.match(reg) || [, event];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    config,
 | 
			
		||||
@ -347,10 +369,10 @@ const parseEntry = function ({ ast, package: module, indexPath }: ParseEntryOpti
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const getASTTokenByTraverse = ({ ast, indexPath }: { ast: any; indexPath: string }) => {
 | 
			
		||||
  let config = '';
 | 
			
		||||
  let value = '';
 | 
			
		||||
  let event = '';
 | 
			
		||||
  let component = '';
 | 
			
		||||
  let config: string | undefined;
 | 
			
		||||
  let value: string | undefined;
 | 
			
		||||
  let event: string | undefined;
 | 
			
		||||
  let component: string | undefined;
 | 
			
		||||
  const importSpecifiersMap: { [key: string]: string } = {};
 | 
			
		||||
  const exportSpecifiersMap: { [key: string]: string | undefined } = {};
 | 
			
		||||
 | 
			
		||||
@ -396,7 +418,11 @@ const getASTTokenByTraverse = ({ ast, indexPath }: { ast: any; indexPath: string
 | 
			
		||||
    visitExportDefaultDeclaration(p) {
 | 
			
		||||
      const { node } = p;
 | 
			
		||||
      const { declaration } = node as any;
 | 
			
		||||
      component = path.resolve(path.dirname(indexPath), importSpecifiersMap[declaration.name]);
 | 
			
		||||
 | 
			
		||||
      if (importSpecifiersMap[declaration.name]) {
 | 
			
		||||
        component = path.resolve(path.dirname(indexPath), importSpecifiersMap[declaration.name]);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.traverse(p);
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
@ -405,7 +431,10 @@ const getASTTokenByTraverse = ({ ast, indexPath }: { ast: any; indexPath: string
 | 
			
		||||
    const exportValue = exportSpecifiersMap[exportName];
 | 
			
		||||
    const importValue = importSpecifiersMap[exportName];
 | 
			
		||||
    const connectValue = exportValue ? importSpecifiersMap[exportValue] : '';
 | 
			
		||||
    const filePath = path.resolve(path.dirname(indexPath), connectValue || importValue || exportValue || '');
 | 
			
		||||
 | 
			
		||||
    const fileName = connectValue || importValue || exportValue || '';
 | 
			
		||||
 | 
			
		||||
    const filePath = fileName ? path.resolve(path.dirname(indexPath), fileName) : '';
 | 
			
		||||
 | 
			
		||||
    if (exportName === EntryType.VALUE) {
 | 
			
		||||
      value = filePath;
 | 
			
		||||
@ -463,7 +492,7 @@ const getDependencies = (dependencies: Record<string, string>, packagePath: stri
 | 
			
		||||
 | 
			
		||||
const setPackages = (packages: ModuleMainFilePath, app: App, packagePath: string, cwd: string, key?: string) => {
 | 
			
		||||
  const { options } = app;
 | 
			
		||||
  const { temp, componentFileAffix, datasoucreSuperClass } = options;
 | 
			
		||||
  const { temp, componentFileAffix = '', datasoucreSuperClass } = options;
 | 
			
		||||
 | 
			
		||||
  let { name: moduleName } = splitNameVersion(packagePath);
 | 
			
		||||
 | 
			
		||||
@ -513,15 +542,45 @@ const setPackages = (packages: ModuleMainFilePath, app: App, packagePath: string
 | 
			
		||||
 | 
			
		||||
  if (!key) return;
 | 
			
		||||
 | 
			
		||||
  if (result.type === PackageType.COMPONENT) {
 | 
			
		||||
  if (result.type === PackageType.COMPONENT || !result.type) {
 | 
			
		||||
    packages.componentPackage[key] = moduleName;
 | 
			
		||||
    // 组件
 | 
			
		||||
    const entry = parseEntry({ ast, package: moduleName, indexPath });
 | 
			
		||||
 | 
			
		||||
    if (entry.component) packages.componentMap[key] = getRelativePath(entry.component, temp);
 | 
			
		||||
    if (entry.config) packages.configMap[key] = getRelativePath(entry.config, temp);
 | 
			
		||||
    if (entry.event) packages.eventMap[key] = getRelativePath(entry.event, temp);
 | 
			
		||||
    if (entry.value) packages.valueMap[key] = getRelativePath(entry.value, temp);
 | 
			
		||||
    if (entry.component) {
 | 
			
		||||
      const packagePath = getRelativePath(entry.component, temp);
 | 
			
		||||
      packages.componentMap[key] = `${packagePath}${
 | 
			
		||||
        packagePath.endsWith(componentFileAffix) ? '' : componentFileAffix
 | 
			
		||||
      }`;
 | 
			
		||||
    } else {
 | 
			
		||||
      packages.componentMap[key] = moduleName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (typeof entry.config === 'string') {
 | 
			
		||||
      if (entry.config) {
 | 
			
		||||
        packages.configMap[key] = getRelativePath(entry.config, temp);
 | 
			
		||||
      } else {
 | 
			
		||||
        packages.configMap[key] = moduleName;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (typeof entry.event === 'string') {
 | 
			
		||||
      if (entry.event) {
 | 
			
		||||
        packages.eventMap[key] = getRelativePath(entry.event, temp);
 | 
			
		||||
      } else {
 | 
			
		||||
        packages.eventMap[key] = moduleName;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (typeof entry.value === 'string') {
 | 
			
		||||
      if (entry.value) {
 | 
			
		||||
        packages.valueMap[key] = getRelativePath(entry.value, temp);
 | 
			
		||||
      } else {
 | 
			
		||||
        packages.valueMap[key] = moduleName;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if (result.type === PackageType.DATASOURCE) {
 | 
			
		||||
    packages.datasourcePackage[key] = moduleName;
 | 
			
		||||
    // 数据源
 | 
			
		||||
    const entry = parseEntry({ ast, package: moduleName, indexPath });
 | 
			
		||||
 | 
			
		||||
@ -530,6 +589,7 @@ const setPackages = (packages: ModuleMainFilePath, app: App, packagePath: string
 | 
			
		||||
    if (entry.event) packages.dsEventMap[key] = getRelativePath(entry.event, temp);
 | 
			
		||||
    if (entry.value) packages.dsValueMap[key] = getRelativePath(entry.value, temp);
 | 
			
		||||
  } else if (result.type === PackageType.PLUGIN) {
 | 
			
		||||
    packages.pluginPakcage[key] = moduleName;
 | 
			
		||||
    // 插件
 | 
			
		||||
    packages.pluginMap[key] = getRelativePath(moduleName, temp);
 | 
			
		||||
  }
 | 
			
		||||
@ -573,11 +633,14 @@ export const resolveAppPackages = (app: App): ModuleMainFilePath => {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const packagesMap: ModuleMainFilePath = {
 | 
			
		||||
    componentPackage: {},
 | 
			
		||||
    componentMap: {},
 | 
			
		||||
    configMap: {},
 | 
			
		||||
    eventMap: {},
 | 
			
		||||
    valueMap: {},
 | 
			
		||||
    pluginPakcage: {},
 | 
			
		||||
    pluginMap: {},
 | 
			
		||||
    datasourcePackage: {},
 | 
			
		||||
    datasourceMap: {},
 | 
			
		||||
    dsConfigMap: {},
 | 
			
		||||
    dsEventMap: {},
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user