Angular基于esbuild打包后@angular/compiler缺失导致运行报错求助
我有一个基于single-spa和SystemJS的壳应用,用于运行各类微前端。现在开发了一个全新的Angular应用,希望使用esbuild构建器进行构建。执行npm run build后生成了main.js文件,但运行该文件时出现如下错误:
Uncaught Error: 可注入项'_G'需要使用JIT编译器进行编译,但'@angular/compiler'不可用。该可注入项属于一个已被部分编译的库,但Angular Linker未对其进行处理,无法回退到JIT编译。
理想情况下,应使用Angular Linker处理该库以实现完整的AOT编译。或者,可通过'@angular/platform-browser-dynamic'或'@angular/platform-server'引导加载JIT编译器,或在引导前手动通过'import "@angular/compiler";'引入编译器。
我认为打包生成的文件应该包含@angular/compiler库,请问这一理解是否正确?
补充:package.json内容
"dependencies": { "@angular-architects/ngrx-toolkit": "^0.1.2", "@angular/animations": "^17.2.0", "@angular/common": "^17.2.0", "@angular/compiler": "^17.2.0", "@angular/core": "^17.2.0", "@angular/elements": "^17.3.0", "@angular/forms": "^17.2.0", "@angular/platform-browser": "^17.2.0", "@angular/platform-browser-dynamic": "^17.2.0", "@angular/router": "^17.2.0", "@ngrx/signals": "^17.1.1", "@ngrx/store": "^17.1.1", "@ngrx/store-devtools": "^17.1.1", "@signicat/pubsub": "^2.0.0", "esbuild": "^0.20.2", "esbuild-plugin-manifest": "^1.0.3", "rxjs": "~7.8.0", "single-spa": "^6.0.1", "single-spa-angular": "^9.0.1", "tslib": "^2.3.0", "zone.js": "~0.14.3" }, "devDependencies": { "@angular-devkit/build-angular": "^17.2.3", "@angular/cli": "^17.2.3", "@angular/compiler-cli": "^17.2.0", "@types/jasmine": "~5.1.0", "jasmine-core": "~5.1.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", "typescript": "~5.3.2" }
你的理解不完全准确。Angular默认AOT编译模式下,@angular/compiler不会被打包进生产构建产物——因为AOT已经在构建阶段完成了模板编译,运行时不需要编译器。但你的场景里出现了需要JIT编译的依赖(错误中的_G可注入项),所以运行时找不到编译器才报错。
问题根源
你依赖的@angular-architects/ngrx-toolkit库可能未经过Angular Linker处理,属于部分编译的库,运行时需要JIT编译器完成剩余编译,但esbuild的生产构建默认排除了@angular/compiler。
解决方案
优先处理库的Linker编译(推荐)
在Angular 17中,对未处理的第三方库,需启用Linker。修改angular.json的构建配置,在architect.build.options里添加:"allowedCommonJsDependencies": ["@angular-architects/ngrx-toolkit"], "linker": true构建时Angular会自动处理该库的部分编译代码,无需JIT编译器。
手动引入@angular/compiler(临时方案)
如果暂时无法处理Linker,可在应用入口文件(如main.ts)顶部手动添加:import "@angular/compiler";这样esbuild会把编译器打包进产物,但会增加包体积,不推荐用于生产环境。
检查single-spa-angular配置
确保single-spa-angular的构建配置与esbuild兼容,在angular.json的singleSpa构建目标中,确认启用了AOT和正确的构建器:"architect": { "build": { "builder": "@angular-devkit/build-angular:application", "options": { "outputPath": "dist", "index": "src/index.html", "browser": "src/main.ts", "polyfills": ["zone.js"], "tsConfig": "tsconfig.app.json", "assets": ["src/favicon.ico", "src/assets"], "styles": ["src/styles.css"], "scripts": [], "aot": true, "linker": true } }, "singleSpa": { "builder": "single-spa-angular:build", "options": { "browserTarget": "your-app:build" } } }
内容的提问来源于stack exchange,提问作者Greggz

