async function bundleComponentMeta()

in packages/build-plugin-lowcode/src/index.js [1232:1322]


async function bundleComponentMeta(webPackConfig, options, pluginOptions, execCompile) {
  const { registerTask, getAllTask, onGetWebpackConfig, context, onHook } = options;
  const { rootDir, pkg: package } = context;
  let { components, engineScope = '@ali', } = pluginOptions || {};
  const {
    devAlias,
    externals = {},
    buildTarget = 'build',
    lowcodeDir = 'lowcode',
  } = pluginOptions || {};
  if (components && !Array.isArray(components)) {
    console.error('[@alifd/build-plugin-lowcode] components must be Array<ComponentName: string>');
    components = null;
  }

  const metaDevSubfix = devAlias ? `.${devAlias}` : '';
  const metaFilename = `meta${metaDevSubfix}`;
  const usedDevComponents = getUsedComponentMetas(rootDir, `meta${metaDevSubfix}`, components);

  const componentsMetaPath = usedDevComponents.map((component) => {
    const componentMetaExportName = `${component}Meta`;
    const componentNameFolder = camel2KebabComponentName(component);
    const componentJsPath = `${lowcodeDir}/${componentNameFolder}/${metaFilename}`;
    const metaJsPath = path.resolve(rootDir, componentJsPath);
    const componentMetaName = `${component}Meta`;
    const componentImportStr = `import ${componentMetaName} from '${metaJsPath}';`;
    const componentMetaPath = generateEntry({
      template: 'component-meta.js',
      filename: `${componentJsPath}.js`,
      rootDir,
      params: {
        componentProps: COMPONENT_PROPS,
        componentImportStr,
        component: componentMetaName,
        execCompile,
        componentMetaExportName,
        version: package.version,
        packageName: package.name,
      },
    });
    return componentMetaPath;
  });

  usedDevComponents.forEach((component, idx) => {
    (function (comp, index) {
      const componentNameFolder = camel2KebabComponentName(comp);
      const taskName = `lowcode-${componentNameFolder}-meta`;
      if (!execCompile || getAllTask().includes(taskName)) return componentsMetaPath;
      registerTask(taskName, getWebpackConfig('production'));
      onGetWebpackConfig(taskName, (config) => {
        const componentMetaExportName = `${comp}Meta`;
        const componentJsPath = `${lowcodeDir}/${componentNameFolder}/${metaFilename}`;
        config.merge({
          entry: {
            [componentJsPath]: componentsMetaPath[index],
          },
        });
        config.output.library(componentMetaExportName).libraryTarget('umd');
        config.output.path(path.resolve(rootDir, `${buildTarget}/${lowcodeDir}`));
        config.externals({ ...COMMON_EXTERNALS_MAP[engineScope], ...externals });
        useStyleLoader(config);
      });
    })(component, idx);
  });

  onHook('after.build.compile', () => {
    usedDevComponents.forEach((comp) => {
      const componentNameFolder = camel2KebabComponentName(comp);
      const componentJsPath = `${lowcodeDir}/${componentNameFolder}/${metaFilename}`;
      const originPath = path.resolve(
        rootDir,
        `${buildTarget}/${lowcodeDir}/${componentJsPath}.js`,
      );

      // 把 meta.js 里面的 window 替换成 this
      const jsContent = fse.readFileSync(originPath, 'utf-8');
      const jsContentTarget = jsContent.replace('window', 'this');
      fse.outputFileSync(originPath, jsContentTarget);

      try {
        const targetPath = path.resolve(
          rootDir,
          `${buildTarget}/${lowcodeDir}/${componentJsPath}.json`,
        );
        fse.outputFileSync(targetPath, JSON.stringify(require(originPath), null, 2));
      } catch (e) {}
    });
  });

  return componentsMetaPath;
}