从 URL 动态加载 React 组件库?

Dynamically load React component library from URL?

我正在为 Typescript 库开发文档工具。这个想法是利用 parcel 的 watch 模式来持续构建库,并在预构建的文档应用程序中使用它。

同样,我需要通过 URL.

动态加载模块库(在另一个项目中构建)
<script type="module">
    const libraryModule = "http://localhost:8080/lib.module.js";
    const promise = import(libraryModule);

    promise.then(library => {
        // do something with library
        window.ComponentLibrary = library;
    });
</script>

但是parcel将上面的import换成require加载失败。使用 System.import 抛出 System is not defined error.

我尝试使用dynamic-import-polyfill然后初始化如下,使用如下:

dynamicImportPolyfill.initialize({
    modulePath: 'http://localhost:13090', // Defaults to '.'
    importFunctionName: '$$import' // Defaults to '__import__'

    const promise = $$import(libPath);
});

这将引发以下错误:

TypeError: Failed to resolve module specifier "react/jsx-dev-runtime". Relative references must start with either "/", "./", or "../"

我也试过使用 script 键入 text/javascript 但也不起作用。

在此处寻找有关加载组件库的最佳方法的指导?

明白了:是的,我们可以将组件库作为模块动态加载。

问题是 React UMD 模块不是纯 ES/Javascript 模块。此外,对于 React 17,JSX 组件是从 react/jsx-runtime 中挑选出来的。因此,首先我必须将 React UMD 模块转换为 ES 模块——它只是一个薄包装器。同样,为 jsx-runtime 添加了一个包装器。要使事情正常进行,必须使用 importmaps,目前所有浏览器都不支持它 - 请参阅 caniuse.com 以检查最新支持。

这样就完成了设置,现在编译为 ES 模块的库可以正常工作了。以下是我用来工作的内容:

<script type="importmap">
        {
            "imports": {
                "react/jsx-runtime": "/react-jsx-runtime.js",
                "react": "/react-as-es-module.js"
            }
        }
    </script>
    <script type="module" src="/component-library.js"></script>
    <script type="module">
        import * as MyComponentLib from "/component-library.js";
        window.ComponentLibrary = { ...MyComponentLib };
    </script>

react-jsx-runtime.js 的代码如下所示:

import * as React from 'react';

export const jsx = React.createElement;
export const jsxs = React.createElement;

react-as-es-module.js 的代码如下:

import 'https://unpkg.com/react@17.0.2/umd/react.production.min.js';

const {
    Children,
    Component,
    Fragment,
    // and all other exports
} = React || {};

export {
    Children,
    Component,
    Fragment,
    // and all other exports
}

export default React;

我使用 ParcelJS 使用 package.json 文件中的 type: "module" 编译了 component-library.js。我很快会在博客 post 和演示 Github 回购中对此进行详细说明。

希望对您有所帮助。