优化后,Angular应用程序中的Angular Element会产生无限重载问题

达蒙·拉科

TL; DR:我正在尝试使用Angular Elements作为Angular应用程序的插件如果我用--prod构建元素,则可以ng serve在我的应用程序上使用(开发设置),但是当我ng serve --prod在我的应用程序上使用它或应用程序之后ng build --prod(生产设置)使用它时,它将进入无限重载

不过,如果我构建添加元素--optimization=false,则可以与我的生产性应用程序一起使用,但不适用于我的开发设置。

关键是,我期待的是建立一个角形元件--prod就可以了,对于两种情况。

问题有没有办法解决这个问题?


现在,长时间阅读。

在工作中,我们尝试在Angular站点中使用可配置的插件,在该站点中,服务器是告知哪个插件处于活动状态的服务器。

我们试图动态地加载Angular模块,但这又是另一回事,我们把它搁置了一天。

因此,除非我们以应有的方式构建所有内容,否则我们接下来要尝试的就是Angular Elements

首先,我开始遵循本教程https://scotch.io/tutorials/build-a-reusable-component-with-angular-elements/amp,并忽略了有关的所有内容,okta因为我的功能有所不同。

创建:

我使用下一条命令创建了核心应用程序,这将是托管插件的应用程序:

  • ng new core --routing --skip-git --style scss --skip-tests --minimal

然后,我使用以下命令创建了一个插件/角度元素:

  • ng new plugin --skip-git --style scss --skip-tests --minimal

插入:

创建完所有内容后,我进入了插件并在中对此行进行了注释polyfills.ts,在该站点的某处阅读到它可以解决NgZone已经加载的问题,这是事实:

// import 'zone.js/dist/zone';  // Included with Angular CLI.

tsconfig.json我换"target": "es5""target": "es2015"为了解决某个问题如何创建元素。不太确定它是如何工作的,但是stackoverflow提出了建议,并且成功了。

app.module.ts根据本教程中的一些想法和类似的内容编辑了如下内容,但丢失了链接:

import { BrowserModule } from '@angular/platform-browser';
import { CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { AppComponent } from './app.component';

@NgModule({
    declarations: [
        AppComponent,
    ],
    imports: [
        BrowserModule,
    ],
    providers: [
    ],
    schemas: [
        CUSTOM_ELEMENTS_SCHEMA,
    ],
    entryComponents: [
        AppComponent,
    ],
})
export class AppModule {
    constructor(private injector: Injector) {
        const elem = createCustomElement(AppComponent, { injector: this.injector });
        customElements.define('my-plugin', elem);
    }

    ngDoBootstrap() {
    }
}

注意:我添加了CUSTOM_ELEMENTS_SCHEMA“原因是我在某个地方找到了它,但是它并没有解决它(而且,我不确定它能做什么)。

在中,app.component.ts我这样做是为了在其模板中显示一些属性:

import { Component } from '@angular/core';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
})
export class AppComponent {
    public content: any = {
        a: 10,
        b: '20',
    }
}

app.component.html看起来像这样:

Some content:
<pre>{{content | json}}</pre>

package.json文件中,我有三个脚本来构建所有脚本:

{
    "scripts": {
        "build": "npm run build:opt && npm run build:noopt",
        "build:opt": "ng build --prod --output-hashing none && node build-elements.js",
        "build:noopt": "ng build --prod --output-hashing none --optimization=false && node build-elements.noopt.js"
    }
}

该文件build-elements.js如下所示(build-elements.noopt.js具有不同的目标名称的文件相同):

'use strict';

const concat = require('concat');
const fs = require('fs-extra');
const path = require('path');

(async function build() {
    const files = [
        './dist/plugin/runtime.js',
        './dist/plugin/polyfills.js',
        './dist/plugin/scripts.js',
        './dist/plugin/main.js',
    ];

    const destinationDir = path.join(__dirname, '../core/src/assets');
    await fs.ensureDir(destinationDir);
    await concat(files, path.join(destinationDir, 'my-plugin.js'));
})();

核心:

对于主机应用程序,我添加了一个名为的组件embedded,并且默认路由使用了该组件

然后,我embedded.component.html使用一些Bootstrap变成了类似的内容

<div id="embedded-container" class="container border border-primary rounded mt-5 p-3" #container>
    <pre>Loading...</pre>
</div>

最后,embedded.component.ts最终像这样显示了实际的加载机制:

import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';

import { environment } from '../../environments/environment';

@Component({
    selector: 'app-embedded',
    templateUrl: './embedded.component.html',
})
export class EmbeddedComponent implements OnInit {
    @ViewChild('container') public container: ElementRef;

    constructor(protected activatedRoute: ActivatedRoute) {
    }

    ngOnInit() {
        this.activatedRoute.queryParams.subscribe((params: Params) => {
            const script = document.createElement('script');
            if (params['how-it-should-be'] !== undefined) {
                script.src = environment.production ? '/assets/my-plugin.js' : '/assets/my-plugin-no-optimization.js';
            } else {
                script.src = environment.production ? '/assets/my-plugin-no-optimization.js' : '/assets/my-plugin.js';
            }
            document.body.appendChild(script);

            const div = document.createElement('div');
            div.innerHTML = '<my-plugin></my-plugin>';

            this.container.nativeElement.innerHTML = '';
            this.container.nativeElement.appendChild(div);
        });
    }
}

运行:

如果我运行ng serve并浏览到http://localhost:4200,则页面加载不会出现问题,注入插件,将新元素添加到DOM并显示来自插件的消息。而且,如果您调试该应用程序,则会看到它已加载/assets/my-plugin.js,该应用程序是为生产而构建的。除了进行调试之外,这不是问题。

然后,如果我运行ng serve --prod(或将其构建用于生产),它也可以正常工作,但会加载/assets/my-plugin-no-optimization.js,该文件是为“调试”而构建的。

这是我最终在实际应用程序上使用的解决方案,但是如您所见,我没有在插件中使用经过优化的代码进行生产,这根本不好。。。

为了证明我的观点,如果我浏览至http://localhost:4200/?how-it-should-be,它将尝试为加载优化的插件,为加载ng serve --prod调试的插件ng serve请注意,这将使您陷入无限重载,请打开浏览器开发人员工具进行查看。


我们使用的最终产品要复杂得多,但是这些示例具有无法真正发挥作用的基本逻辑。

我还以此创建了一个GitHub存储库,您可以在其中查看这些代码,并尝试自己解决问题,或者以示例的方式提出自己的想法。

如果您想知道如何使用--optimization=falsekinda修复它,那么,我正在尝试调试此问题(事实证明这是不可能的),然后突然加载了它。

我查看了一下时间,对于生产部署来说,我来得太迟了两个小时,所以我添加了这种丑陋的机制来根据环境加载不同的构建。它在开发和生产中都有效,但是我对此并不感到骄傲。


抱歉,如果我的英语不好...不,不,我的英语不好,对不起^ __ ^

Zakk L.

我找到了解决方案!

事实证明,问题在于在同一个上下文中运行多个webpack项目。我对问题的理解实质上是,当您使用webpack构建项目时,它们会在运行时进行一些webpack引导,并依赖于全局上下文(webpackJsonp)中定义的特定功能当多个webpack配置尝试在同一DOM上下文中进行自举时,它将创建此处定义的症状。(在这里找到更详细的解释-https: //github.com/angular/angular/issues/23732#issuecomment-388670907

这个GitHub注释描述了一个解决方案,但没有介绍方法-https: //github.com/angular/angular/issues/30028#issuecomment-489758172下面,我将展示我是如何具体解决的。

我们可以使用webpack配置为我们的Web组件重命名webpackJsonp,以使两个Angular项目(或任何使用webpack构建的项目)都不会相互干扰。

首先,我们安装@ angular-builders / custom-webpack软件包,以使我们能够在Angular CLI中修改内置的webpack配置。

npm install --save-dev @angular-builders/custom-webpack

接下来,我们更新angular.json文件,以使用新的构建器和名为的选项中的新属性值customWebpackConfig这包括我们将要创建的新文件的路径以及mergeStrategy。这种合并策略表示我们想将配置附加到outputwebpack配置部分。

angular.json
...
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./extra-webpack.config.js",
              "mergeStrategies": { "output": "append"}
            },
...

最后,我们只需将extra-webpack.config.js文件添加到包含angular.json的目录中即可。该文件仅包含以下内容:

module.exports = {
    output: {
        jsonpFunction: '<webcomponent-prefix>-webpackJsonp'
    }
}

如果将其更改为其他值,则jsonpFunction默认值为webpackJsonp,它将起作用。我决定保留函数名称,但为Web组件应用程序添加前缀。从理论上讲,您可以在相同的DOM上下文中运行N个Webpack配置,只要每个配置都有唯一的jsonpFunction

再次构建您的Web组件,瞧,它起作用了!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

服务注入到组件后,如何解决加载Angular应用程序中的问题?

来自分类Dev

Angular 应用程序陷入无限循环

来自分类Dev

即使在访问令牌更新后,Angular 应用程序也会自动注销

来自分类常见问题

IE11中的Angular4应用程序运行问题

来自分类Dev

Angular应用程序中聚合物模板的数据绑定问题

来自分类Dev

在应用程序初始化中检查本地存储的Angular 6问题

来自分类Dev

在angular 9应用程序中托管基于照明元素的Web组件的问题

来自分类Dev

github页面上Angular2应用程序中的路径问题

来自分类Dev

d3js / Angular 8应用程序问题

来自分类Dev

Angular 2-基于文件的应用程序的路由问题

来自分类Dev

自动构建 angular cli 应用程序缓存文件问题

来自分类Dev

Heroku 上的 Angular 应用程序部署问题

来自分类Dev

Angular 2 AoT编译会导致应用程序问题并在JiT中正常运行

来自分类Dev

使用运算符重载的程序会产生垃圾输出

来自分类Dev

C ++处理输入文件中的数据会产生无限循环

来自分类Dev

Angular 2应用程序和Angular 2路由器的异步性问题

来自分类Dev

针对不同密度优化应用程序导致问题

来自分类Dev

为什么对不同的ASP.NET Core端点发出约20个请求后,Angular应用程序HTTP请求会挂起?

来自分类Dev

在android中更新应用程序后,后台服务会怎样?

来自分类Dev

更新应用程序后,文档目录中存储的文件会如何处理?

来自分类Dev

单击面板中的Opera图标后,为什么设置应用程序会启动?

来自分类Dev

几分钟后,ASP.NET MVC + NHibernate + Oracle应用程序中的连接问题

来自分类Dev

iOS Swift应用程序内存问题-运行后从内存中删除功能?

来自分类Dev

更新到 ubuntu 18.04 后,我在某些应用程序中遇到声音问题

来自分类Dev

当应用程序包含令牌时,Angular $http.get 会失败?

来自分类Dev

设置应用程序设置后,Azure Functions应用程序产生错误

来自分类Dev

角度引导问题angular.bootstrap在我的应用程序上不起作用

来自分类Dev

WCF CORS问题-WPF应用程序成功连接但Angular App抛出405

来自分类Dev

部署Spring Boot + Angular应用程序时出现问题

Related 相关文章

  1. 1

    服务注入到组件后,如何解决加载Angular应用程序中的问题?

  2. 2

    Angular 应用程序陷入无限循环

  3. 3

    即使在访问令牌更新后,Angular 应用程序也会自动注销

  4. 4

    IE11中的Angular4应用程序运行问题

  5. 5

    Angular应用程序中聚合物模板的数据绑定问题

  6. 6

    在应用程序初始化中检查本地存储的Angular 6问题

  7. 7

    在angular 9应用程序中托管基于照明元素的Web组件的问题

  8. 8

    github页面上Angular2应用程序中的路径问题

  9. 9

    d3js / Angular 8应用程序问题

  10. 10

    Angular 2-基于文件的应用程序的路由问题

  11. 11

    自动构建 angular cli 应用程序缓存文件问题

  12. 12

    Heroku 上的 Angular 应用程序部署问题

  13. 13

    Angular 2 AoT编译会导致应用程序问题并在JiT中正常运行

  14. 14

    使用运算符重载的程序会产生垃圾输出

  15. 15

    C ++处理输入文件中的数据会产生无限循环

  16. 16

    Angular 2应用程序和Angular 2路由器的异步性问题

  17. 17

    针对不同密度优化应用程序导致问题

  18. 18

    为什么对不同的ASP.NET Core端点发出约20个请求后,Angular应用程序HTTP请求会挂起?

  19. 19

    在android中更新应用程序后,后台服务会怎样?

  20. 20

    更新应用程序后,文档目录中存储的文件会如何处理?

  21. 21

    单击面板中的Opera图标后,为什么设置应用程序会启动?

  22. 22

    几分钟后,ASP.NET MVC + NHibernate + Oracle应用程序中的连接问题

  23. 23

    iOS Swift应用程序内存问题-运行后从内存中删除功能?

  24. 24

    更新到 ubuntu 18.04 后,我在某些应用程序中遇到声音问题

  25. 25

    当应用程序包含令牌时,Angular $http.get 会失败?

  26. 26

    设置应用程序设置后,Azure Functions应用程序产生错误

  27. 27

    角度引导问题angular.bootstrap在我的应用程序上不起作用

  28. 28

    WCF CORS问题-WPF应用程序成功连接但Angular App抛出405

  29. 29

    部署Spring Boot + Angular应用程序时出现问题

热门标签

归档