function createAlfaWidget()

in packages/react/alfa-react/src/createAlfaWidget.tsx [35:134]


function createAlfaWidget<P = any>(option: AlfaFactoryOption): React.FC<any> {
  const {
    name, dependencies, priority, dynamicConfig,
    manifest, loading, lazyLoad, delay,
  } = option || {};

  if (name.match(/@ali\/widget-/)) {
    // TODO load style
    return createCWSWidget<P>(option);
  }

  // check app option
  if (!name) return () => null;

  let preLoader: () => Promise<any>;

  if (priority === 'high' && !IS_SSR) {
    const p = loader.register({
      ...option,
      // 必须设置 container,否则沙箱会创建插入一个新的 body
      container: document.body,
      dynamicConfig: typeof dynamicConfig === 'boolean' ? dynamicConfig : !manifest,
    });

    preLoader = async () => p;
  }

  const passedInOption = { ...option };

  // 非 oneConsole 环境下设置 iframe 沙箱地址为 about:blank
  // 避免沙箱创建失败
  if (passedInOption.sandbox && !passedInOption.sandbox.sandBoxUrl && !isOneConsole()) {
    passedInOption.sandbox.sandBoxUrl = 'about:blank';
  }

  const useDelay = () => {
    return useMemo(() => {
      if (typeof delay === 'number') {
        return new Promise<void>((resolve) => {
          setTimeout(() => {
            resolve();
          }, delay);
        });
      }

      if (typeof delay === 'function') {
        const fnReturn = delay();
        if (typeof fnReturn.then === 'function') return fnReturn;
        if (typeof fnReturn === 'number') return fnReturn;
      }

      return undefined;
    }, []);
  };

  if (priority === 'low' && !IS_SSR) {
    return (props: P & IProps) => {
      const delayPromise = useDelay();

      // Compatible with old logic
      // props should not passed in errorBoundary
      return (
        <LazyLoad
          placeholder={<Loading loading={loading} />}
          {...{ ...lazyLoad }}
        >
          <ErrorBoundary {...props}>
            <Application
              {...passedInOption}
              delayPromise={delayPromise}
              style={props.style || passedInOption.style}
              deps={dependencies || {}}
              customProps={{ ...props }}
              preLoader={preLoader}
            />
          </ErrorBoundary>
        </LazyLoad>
      );
    };
  }

  return (props: P & IProps) => {
    const delayPromise = useDelay();

    // Compatible with old logic
    // props should not passed in errorBoundary
    return (
      <ErrorBoundary {...props}>
        <Application
          {...passedInOption}
          delayPromise={delayPromise}
          style={props.style || passedInOption.style}
          deps={dependencies || {}}
          customProps={{ ...props }}
          preLoader={preLoader}
        />
      </ErrorBoundary>
    );
  };
}