Динамически загружать библиотеку компонентов React из URL-адреса?

Я работаю над инструментом документации для библиотеки Typescript. Идея состоит в том, чтобы использовать режим просмотра участка для непрерывного создания библиотеки и использовать его в предварительно созданном приложении для документации.

Для того же мне нужно динамически загружать библиотеку модулей (построенную в другом проекте) через 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>

Однако посылка заменяет вышеуказанное 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но тоже не работает.

Ищете руководство о том, как лучше всего загрузить библиотеку компонентов?

1 ответ

Разобрался: да, мы можем динамически загружать библиотеку компонентов как модуль.

Проблема заключалась в том, что модуль 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;

я скомпилировал component-library.jsс помощью ParcelJS с помощью type: "module"в package.jsonфайл. Я скоро подробно расскажу об этом в посте в блоге и демо-репозитории Github.

Надеюсь это поможет.

Другие вопросы по тегам