Angular 16中使用apollo-angular出现React依赖缺失构建错误
问题背景
在Angular 16项目中使用以下版本的Apollo依赖:
"@apollo/client": "^3.8.7", "apollo-angular": "^5.0.2", "graphql": "^16.8.1",
AppModule中的APOLLO_OPTIONS配置如下:
providers: [ { provide: APOLLO_OPTIONS, useFactory(httpLink: HttpLink) { return { cache: new InMemoryCache(), link: httpLink.create({ uri: uri, }), defaultOptions: { watchQuery: { fetchPolicy: 'cache-and-network', errorPolicy: 'ignore', }, } }; }, deps: [HttpLink], } ],
构建时出现大量无法解析React模块的错误,示例错误包括:
./node_modules/@apollo/client/react/context/ApolloConsumer.js:2:0-31 - Error: Module not found: Error: Can't resolve 'react' in '.../node_modules/@apollo/client/react/context'
以及一系列TypeScript类型错误(找不到React模块或类型)。
问题原因
@apollo/client是跨框架的GraphQL客户端,默认包含React、Vue等多框架的绑定实现。当你从@apollo/client根模块导入核心类(比如InMemoryCache)时,打包工具会尝试解析整个包的依赖,包括React相关代码。而Angular项目中没有安装React依赖,因此触发模块找不到的错误。
解决方案
1. 修正核心模块的导入路径
将所有从@apollo/client导入的核心类(如InMemoryCache、ApolloClient等)改为从@apollo/client/core导入,仅加载Angular所需的核心功能:
// 错误导入 import { InMemoryCache } from '@apollo/client'; // 正确导入 import { InMemoryCache } from '@apollo/client/core';
修改AppModule中的导入后,重新构建即可避免React相关代码被打包。
2. 使用Apollo Angular专属API
确保组件中使用apollo-angular提供的服务和指令,而非@apollo/client的React绑定API:
示例组件代码(使用Apollo服务的watchQuery):
import { Component, OnInit } from '@angular/core'; import { Apollo } from 'apollo-angular'; import gql from 'graphql-tag'; @Component({ selector: 'app-user', template: ` <div *ngIf="loading">加载中...</div> <div *ngIf="error">错误:{{ error.message }}</div> <div *ngIf="data">用户名:{{ data.user.name }}</div> ` }) export class UserComponent implements OnInit { loading = false; error: any; data: any; constructor(private apollo: Apollo) {} ngOnInit(): void { this.apollo.watchQuery({ query: gql` query GetCurrentUser { user { name } } ` }).valueChanges.subscribe(result => { this.loading = result.loading; this.error = result.error; this.data = result.data; }); } }
3. 临时修复(不推荐)
如果仍有类型错误,可以临时安装React的类型依赖作为兜底,但这并非最优解(因为Angular不需要React):
npm install --save-dev @types/react
总结
通过从@apollo/client/core导入核心模块,避免加载React相关代码,即可解决构建时的React模块找不到错误。同时确保使用apollo-angular提供的专属API,适配Angular生态。
内容的提问来源于stack exchange,提问作者Masum Mollik

