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

Angular 17跨工作区导入独立组件构建失败求助

跨Angular工作区导入独立组件的构建问题及解决思路

操作步骤

git clone https://github.com/thomaspeugeot/multi_ws_issue.git
cd multi_ws_issue
cd a
npm i
ng build

异常结果

$ ng build
Application bundle generation failed. [6.929 seconds]

X [ERROR] Could not resolve "@angular/core"

    ../b/src/app/b/b.component.ts:1:26:
      1 │ import { Component } from '@angular/core';
        ╵                           ~~~~~~~~~~~~~~~
...

问题分析

仓库包含两个Angular工作区目录a和b,a的根组件直接导入b工作区的独立组件BComponent:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

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

import { BComponent } from '../../../b/src/app/b/b.component'


@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BComponent,
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

执行上述ng build步骤时,无法解析BComponent的依赖,必须先在b工作区执行npm i才能成功构建,但这种方式会占用大量磁盘空间(实际场景需导入多个工作区组件,node_modules可达数GB)。Angular 16时该方式可行,但17版本失效,且独立组件本应减少NgModules依赖。

诉求

寻求a工作区的配置方案,实现跨工作区直接导入独立组件,且保留esbuild构建工具。

尝试方案及后续错误

在a的tsconfig.json中添加路径配置:

"paths": {
      "*": [
        "./node_modules/*"
      ]
    }

编译成功但运行时出现错误:

ERROR Error: NG0203: inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`.
    Angular 46
    <anonymous> main.ts:5
core.mjs:6531:22
...

错误解释与解决思路

错误原因

这个错误源于跨工作区导入的BComponent使用了Angular依赖注入(如inject()函数),但当前构建流程未让Angular编译器正确处理该组件代码,导致依赖注入上下文丢失。

直接导入b工作区的源码文件时,esbuild仅做简单打包,未经过Angular编译器(ngc)处理。而独立组件的依赖注入逻辑需要Angular编译器生成的注入上下文代码才能正常运行。添加的paths配置虽然解决了编译时依赖解析问题,但BComponent的代码未被Angular编译流程正确转换,运行时无法找到注入上下文。

解决思路

  1. 将组件打包为Angular库:

    • 在b工作区通过ng generate library创建库项目,把BComponent封装到库中,执行ng build生成库产物。然后在a工作区通过npm link ../b/dist/your-library本地链接,或直接引用打包后的产物。这种方式下组件会被Angular编译器正确处理,包含完整的注入上下文逻辑,且无需在b工作区安装全量依赖。
  2. 使用工作区共享依赖:

    • 在根目录创建package.json,启用pnpm/yarn的工作区功能(pnpm workspaces/yarn workspaces),让a和b共享同一套node_modules,避免重复安装。同时修改a的tsconfig.json:
      "paths": {
        "@b/*": ["../b/src/app/*"]
      },
      "include": ["../b/src/app/**/*.ts"]
      
    • 还要在a的angular.json中配置build选项,让esbuild包含b的源码文件,确保Angular编译流程覆盖这些文件。
  3. 导入预编译组件产物:

    • 避免直接导入b的源码,先在b工作区执行ng build生成预编译产物,然后在a中导入b/dist目录下的组件文件。预编译后的组件已包含正确的注入上下文,可直接正常运行。

内容的提问来源于stack exchange,提问作者thomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 18:17:35