javascript - 在浏览器中使用带有外部 URL 的动态导入
问题描述
是否有 Babel 插件或 polyfill 将转换动态导入调用,因此以下代码将在浏览器中工作:
const namespace = await import('https://example.com/bundle.js');
console.log(namespace.exportedSymbol);
如果不是,也许可以将其转换为 SystemJS 导入,因此可以在运行时使用 SystemJS 加载器来加载外部包?
// transformed code:
import System from 'systemjs';
const namespace = await System.import('https://example.com/bundle.js');
console.log(namespace.exportedSymbol);
我不想用 XHR/Fetch 自己实现动态加载,我希望源代码尽可能接近 EcmaScript 的发展方向(未来兼容性)。
解决方案
一般说明
首先我要提到的是,它import
是 EcmaScript 中的一个特殊关键字,因此不可能透明地填充它。
唯一的选择是调用另一个函数,该函数将检测本地是否支持动态导入并相应地切换实现。
好消息是Rollup有一个选项output.dynamicImportFunction
,它允许在编译期间重命名动态导入,因此您可以在源代码中使用标准导入。
因此,如果您使用SystemJS,您可以将其设置为:
{
output: {
dynamicImportFunction: 'System.import',
},
}
Webpack 具有用于转换动态导入的内置机制,但它更适合代码拆分用例,并且不适用于外部导入。我相信您可以告诉 Webpack 使用该import(/* webpackIgnore: true */ 'https://example.com/bundle.js');
构造忽略此类导入,但您还需要import
使用文本替换插件或类似的东西将函数名称替换为其他名称。
填充物
看起来动态导入的最佳 polyfill 是 GoogleChromeLabs 的dynamic-import- polyfill。
你可以在你的入口点像这样初始化它:
import dynamicImportPolyfill from 'dynamic-import-polyfill';
dynamicImportPolyfill.initialize();
您还可以传递一个基本 URL,将从中解析相对 URL,以及__import__()
默认情况下应该填充的函数的名称(它是 )。
为了将它与 Rollup 一起使用,您将需要以下配置:
{
output: {
dynamicImportFunction: '__import__',
},
}
或者您需要使用import()
替换__import__()
插件在 Webpack 中替换为。
这个 polyfill 的缺点是它依赖于一些旧版浏览器不支持的 ESM 功能,因此它无法在Internet Explorer 11中运行。
此外,它使用动态创建的脚本,代码内容作为 blob src 传递。如果您使用CSP 策略,则应更新它们以允许使用blob:
URL。
推荐阅读
- xml - 如何在 XSLT3.0 中将空行从 xml 删除到 CSV 输出
- c - 在C中使用队列反转堆栈
- javascript - 如何使用 Observable 启动下一个异步任务
- python - 23.2 项目 2:使用 LOOPS 进行数据可视化
- go - 使用 GORM 和 echo-framework 进行更新的惯用方式
- apache-kafka - Kafka 的消费者线程数应该等于主题分区数
- reactjs - react-router-dom history.goBack() 在 Firefox 和 Safari 上不起作用
- javascript - 使用 jQuery 从 URL 页面中的 HTML 元素中读取实时值
- r - 如何使用 apply 函数为一行所有数字提供值 100 的条件
- android - 使用存储访问框架 (SAF) 选择或创建外部文件