【问题标题】:Can I dynamically import a JS module that uses rxjs into an Angular App我可以将使用 rxjs 的 JS 模块动态导入到 Angular 应用程序中吗
【发布时间】:2022-08-02 18:53:06
【问题描述】:

我已经用 Angular 12 构建了一个应用程序。

我有一个名为 dynamic_module.js 的 JS 模块,它在构建时不可用,我想在应用程序中导入和使用它。但是,dynamic_module.js 使用 rxjs 和其他导入——所有这些都已在 Angular 应用程序中使用,因此包含在构建的 webpack 中。 dynamic_module 不是 Angular / webpack 工件或任何复杂的东西 - 它是位于同一服务器上的简单 JavaScript 文件但在构建时不可用.

当我尝试使用 import(<path_to_dynamic_module.js> ) 函数导入 \"dynamic_module.js\" - (我假设此方法被 webpack 劫持)我收到一个错误:

\"错误:找不到模块 \'<path_to_dynamic_module.js>\' \"。

我预料到了这一点,因为在构建应用程序时 dynamic_module.js 不可用。

所以,我尝试了在标题中插入&lt;script&gt; 元素的方法——

例如&lt;script type=\"module\" src=\"&lt;url_of_dynamic_module.js&gt;\"&gt;&lt;/script&gt;

这会加载模块但报告错误:

无法解析模块说明符 \"rxjs\"。相对的 引用必须以 \"/\"、\"./\" 或 \"../\" 开头。

我也试过这个,没有在模块中导入 rxjs,它工作正常。

如果我尝试将 SystemJS 与 babel 转译器一起使用并尝试导入 dynamic_module.js,当 System JS 尝试加载它转到 http 的 rxjs 模块时,我会收到错误消息。

错误:获取错误:404 Not Found 实例化 http://localhost:4400/rxjs

当从 dynamic_module.js 中删除导入时,这也有效。

我的问题是:使用 SystemJS(或任何其他方法)动态加载的模块是否可以导入已经由 webpack 加载的其他模块 - 无需复制或通过 http 重新加载?

如果这是不可能的,我可以通过 http 使 SystemJS 加载所有必要的模块文件(我已经使用 SystemJS 的 \'babel\' 转译器模块完成了这个)。这会导致模块的两个副本(即本例中的 rxjs)被加载到浏览器中 - 这可能是一个严重的问题(空间/性能/冲突......)吗?

这是该模块的一个非常简单的示例-如果删除了导入,则可以通过任何方法加载,但在如果包含导入.

动态模块.js

import { Observable} from \'rxjs\';
export class MyClass{
   hello( msg ) { 
     console.log(\'[MODULE] Hello World\');
     console.log(msg);
   }
}

感谢您的任何建议!

  • 为了涵盖所有可能性,我重试了 import() 函数(即 Angular 中可用的函数 - 可能是 \"webpack\" 函数。),其中包含指向\"dynamic_module.js\" 的位置 - 这也失败了:\"错误:找不到模块 \'http://....\'

标签: javascript angular webpack systemjs


【解决方案1】:

好的,经过一些研究,我解决了我的问题:

让我简明扼要地描述一下我遇到的问题:

  • 我试图将模块 (dynamic_module.js) 导入 Angular 运行时的应用程序,
  • 该模块依赖于已捆绑的模块 Angular webpack (rxjs)
  • 我使用 SystemJS 导入我的动态模块
  • SystemJS 尝试通过以下方式解决我的 dynamic_module 的依赖项 从服务器重新加载模块。
  • 我觉得这是不必要的,因为模块已经存在于客户端应用程序中 - 无论如何,http 请求失败了,因为在它寻找它们的地方找不到依赖关系。

解决方案是提前让 SystemJS 知道依赖项已经可用。这是使用 SystemJS.set() 方法完成的:例如,在我的情况下,关键步骤是:

import * as rxjs from "rxjs";

SystemJS.set('rxjs', SystemJS.newModule(rxjs));

SystemJS.import( <url_of_module> ).then( module=>.....});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 2017-04-15
    • 2020-06-01
    • 2017-07-30
    • 2018-10-27
    • 2013-07-30
    • 2017-08-20
    相关资源
    最近更新 更多