You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Angular 17 Elements组件集成到ASP.NET WebForms应用中?

问题:ASP.NET WebForms集成Angular 17 Elements时出现模块语法错误

我有一个运行.NET 4.5的ASP.NET WebForms应用,参照教程构建了包含Angular Elements和Angular Material Table的Angular 17应用。构建后将生成的JS和样式文件引入WebForms页面,浏览器控制台报错:

Uncaught SyntaxError: Unexpected token 'export'        chunk-HH4V2P6H.js:7
Uncaught SyntaxError: Cannot use import statement outside a module        chunk-OH42BLK4.js:1
Uncaught SyntaxError: Cannot use import statement outside a module        main.js:1

相关配置文件如下:

angular.json 配置

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "MatTableElements": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss",
          "standalone": false
        },
        "@schematics/angular:directive": {
          "standalone": false
        },
        "@schematics/angular:pipe": {
          "standalone": false
        }
      },
      "root": "projects/mat-table-elements",
      "sourceRoot": "projects/mat-table-elements/src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            "outputPath": "dist/mat-table-elements",
            "index": "projects/mat-table-elements/src/index.html",
            "browser": "projects/mat-table-elements/src/main.ts",
            "polyfills": [
              "zone.js"
            ],
            "tsConfig": "projects/mat-table-elements/tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": [
              "projects/mat-table-elements/src/favicon.ico",
              "projects/mat-table-elements/src/assets"
            ],
            "styles": [
              "@angular/material/prebuilt-themes/indigo-pink.css",
              "projects/mat-table-elements/src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "1500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "none",
              "optimization": {
                "scripts": true,
                "styles": {
                  "minify": true,
                  "inlineCritical": false
                },
                "fonts": true
              }
            },
            "development": {
              "optimization": false,
              "extractLicenses": false,
              "sourceMap": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "buildTarget": "MatTableElements:build:production"
            },
            "development": {
              "buildTarget": "MatTableElements:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "MatTableElements:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": [
              "zone.js",
              "zone.js/testing"
            ],
            "tsConfig": "projects/mat-table-elements/tsconfig.spec.json",
            "inlineStyleLanguage": "scss",
            "assets": [
              "projects/mat-table-elements/src/favicon.ico",
              "projects/mat-table-elements/src/assets"
            ],
            "styles": [
              "@angular/material/prebuilt-themes/indigo-pink.css",
              "projects/mat-table-elements/src/styles.scss"
            ],
            "scripts": []
          }
        }
      }
    }
  }
}

app.module.ts(非独立组件版本)

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


import { ItemAssignmentsComponent } from './item-assignments/item-assignments.component';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';


@NgModule({
  declarations: [
    ItemAssignmentsComponent
  ],
  imports: [
    BrowserModule,
    MatTableModule,
    MatPaginatorModule
  ],
  providers: [
    provideAnimationsAsync()
  ]
  // entryComponents: [ItemAssignmentsComponent]
})
export class AppModule implements DoBootstrap { 
  constructor(private injector: Injector) {
    const el = createCustomElement(ItemAssignmentsComponent, {injector});
    customElements.define('item-assignment', el);
  }

  ngDoBootstrap(appRef: ApplicationRef): void {
      
  }

}

WebForms页面引入代码

<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
    <link rel="stylesheet" type="text/css" href="assets/css/moog-default.css" />
    <link rel="stylesheet" type="text/css" href="assets/css/moog-layout.css" />
    <link rel="stylesheet" type="text/css" href="assets/js/item-data-report/styles.css" />

    
    <script type="text/javascript" src="assets/js/item-data-report/chunk-HH4V2P6H.js"></script>
    <script type="text/javascript" src="assets/js/item-data-report/chunk-OH42BLK4.js"></script>
    <script type="text/javascript" src="assets/js/item-data-report/main.js"></script>
    <script type="text/javascript" src="assets/js/item-data-report/polyfills.js"></script>
    
    
    <item-assignment></item-assignment>
</asp:Content>

tsconfig.json

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "sourceMap": true,
    "declaration": false,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "ES2022",
    "module": "ES2022",
    "useDefineForClassFields": false,
    "lib": [
      "ES2022",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

更新:已重构为独立组件,但错误依旧。


解决方案

错误核心原因:Angular 17默认输出ES模块格式,但ASP.NET WebForms的传统脚本引入方式不支持import/export语法。以下两种方案可解决问题:

方案1:修改Angular构建配置,输出兼容传统脚本的IIFE格式

  1. 打开angular.json,在projects.MatTableElements.architect.build.options中添加format配置,指定输出格式为iife:
"options": {
  // 保留原有所有配置
  "format": ["iife"]
}
  1. 在production构建配置中添加singleBundle选项,将所有代码合并为单个文件:
"configurations": {
  "production": {
    // 保留原有所有配置
    "singleBundle": true
  }
}
  1. 重新执行生产构建:ng build --configuration production
  2. 此时dist目录会生成main.iife.js,只需在WebForms页面引入这一个文件即可,无需引入其他chunk:
<script type="text/javascript" src="assets/js/item-data-report/main.iife.js"></script>

方案2:在WebForms页面声明脚本为ES模块

若不想修改Angular构建配置,可将脚本的type改为module,同时调整加载顺序(polyfills需优先加载):

<script type="module" src="assets/js/item-data-report/polyfills.js"></script>
<script type="module" src="assets/js/item-data-report/chunk-HH4V2P6H.js"></script>
<script type="module" src="assets/js/item-data-report/chunk-OH42BLK4.js"></script>
<script type="module" src="assets/js/item-data-report/main.js"></script>

注意:该方式要求浏览器支持ES模块,若需兼容旧版IE浏览器,优先选择方案1。

额外检查项

  • 若需兼容旧浏览器(如IE11),需将tsconfig.json中的target改为ES5,并添加core-js等必要polyfills。
  • 独立组件版本需确保createCustomElement使用正确:
import { createCustomElement, Injector } from '@angular/elements';
import { ItemAssignmentsComponent } from './item-assignments/item-assignments.component';
import { bootstrapApplication, inject } from '@angular/platform-browser';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';

bootstrapApplication(ItemAssignmentsComponent, {
  providers: [provideAnimationsAsync()]
}).then(() => {
  const el = createCustomElement(ItemAssignmentsComponent, { injector: inject(Injector) });
  customElements.define('item-assignment', el);
});

内容的提问来源于stack exchange,提问作者ben.kansas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:13:14