来自不同脚本的多个 Angular 元素

Multiple Angular Elements from different scripts

是否可以使用从不同脚本生成的 Angular Elements

我有 2 个项目天气小部件和时钟小部件,它们生成自己的脚本(连接所有必需的脚本)。

当我单独使用这些小部件时,它工作正常,但当它们在同一页面上使用时,出现如下所示的错误:

DOMException: Failed to execute 'define' on 'CustomElementRegistry': this name has already been used with this registry
at CustomElementRegistry.define (http://172.27.147.64:8080/node_modules/document-register-element/build/document-register-element.js:2:18538)
at new AppModule (http://172.27.147.64:8080/dist/weather-widget/main.js:115:24)

目前不支持在同一页面上有多个 angular 个微应用的功能。

您看到的错误实际上很好地描述了问题。当您加载第二个微型应用程序时,bootstrap 将 运行 并尝试通过调用它的 ngDoBootstrap 方法来 bootstrap 模块。如果你做了一些详细的日志记录,你会注意到它第二次尝试在第一个微应用程序上调用 ngDoBootstrap。如果你想让这个工作,你需要做一些手动工作来自己控制 bootstrap 过程,并确保 bootstrap 在页面上引入正确的模块。

Resource

分发资产 webpack 的构建默认分配 window.webpackJsonp 变量,但是当多个元素以这种方式包装时,您将在解析捆绑包时分配该变量并使用现有代码运行。

您可以通过在捆绑过程中为该变量指定一个更独特的名称来猴子修补它。 我只是将元素名称添加到 webpackJsonp 的名称中,这解决了这个问题。

只是为了更新这个,以便其他用户找到解决方案。现在可以使用 Angular Custom Webpack Builder.

在angular.json

      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./apps/custom-elements/extra-webpack.config.js",
              "mergeStrategies": { "externals": "replace" }
            },
            ...

然后在 extra-webpack.config.js 文件中添加如下内容:

module.exports = {
  output: {
    jsonpFunction: 'webpackJsonpElements',
    library: 'elements',
  },
}

如果它仍然不起作用,请尝试 adding/removing Polyfills.ts 文件中的 polyfill 和 adding/removing custom-elements-es5-adapter.js which you can pull from here

万一这对以后的任何人都有帮助,重置 webpack 创建的全局变量为我解决了这个问题。例如加载页面 A,这是一个 angular 元素应用程序,然后加载页面 B,这是另一个 angular 元素应用程序。在页面加载时一定要重置 webpackJsonp = [].