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