从 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 回购中对此进行详细说明。
希望对您有所帮助。
我正在为 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 回购中对此进行详细说明。
希望对您有所帮助。