Angular v12集成d3、nvd3编译正常但运行时提示d3未定义
解决Angular v12中集成d3与nvd3运行时"d3 is not defined"错误
问题背景
在Angular v12项目中直接集成原生d3、nvd3(未使用ng2-nvd3封装库),编译环节无异常,但运行时抛出ReferenceError: d3 is not defined错误。
错误详情
default-node_modules_d3_src_index_js.js:2 ERROR Error: Uncaught (in promise): ReferenceError: d3 is not defined ReferenceError: d3 is not defined at nv.d3.js:18:7 at 75301 (nv.d3.js:15671:2) at __webpack_require__ (bootstrap:19:1) at 89275 (src_app_mypage_module_ts.js:15:62) at __webpack_require__ (bootstrap:19:1) at 13111 (pageone.component.html:2:39) at __webpack_require__ (bootstrap:19:1) at Function.__webpack_require__ (bootstrap:19:1) at _ZoneDelegate.invoke (zone.js:368:26) at resolvePromise (zone.js:1193:31) at resolvePromise (zone.js:1147:17) at zone.js:1260:17 at _ZoneDelegate.invokeTask (zone.js:402:31) at core.mjs:25948:55 at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:25948:36) at _ZoneDelegate.invokeTask (zone.js:401:60) at Object.onInvokeTask (core.mjs:26249:33) at _ZoneDelegate.invokeTask (zone.js:401:60) at Zone.runTask (zone.js:173:47)
已执行操作
npm install d3 npm install nvd3 npm install @types/d3 --save-dev npm install @types/nvd3 --save-dev
现有代码
组件HTML
<div id='chart' class='span4'> <svg style='height:500px;width:100%'> </svg> </div>
组件TS
import * as d3 from 'd3'; import * as nv from 'nvd3'; ngOnInit(): void { this.myservice.subscribe(resp=> { this.chartdata = resp.data; this.drawchart(); }); } drawchart() { nv.addGraph(()=> { var chart = nv.models.pieChart() .x((d) => { return d.label }) .y((d) => { return d.value }) .showLabels(true) .donut(true) .labelThreshold(0.001) .labelType("key").donutRatio(0.60); d3.select("#chart svg") .datum(this.chartdata) .call(chart as any); // ... 其余逻辑 }); }
可行解决方案
1. 锁定适配版本的依赖
nvd3 v1.8.6与d3 v5.x版本适配性最佳,先安装指定版本:
npm install d3@^5.16.0 nvd3@1.8.6 --save npm install @types/d3@^5 @types/nvd3 --save-dev
2. 全局暴露d3供nvd3调用
nvd3依赖全局作用域下的d3变量,需在angular.json中配置脚本引入,让webpack在打包时将d3和nvd3注入全局:
打开angular.json,找到architect > build > options > scripts数组,添加:
"scripts": [ "node_modules/d3/dist/d3.min.js", "node_modules/nvd3/build/nv.d3.min.js" ]
3. 调整组件代码的引用方式
移除组件内的import * as d3 from 'd3'和import * as nv from 'nvd3',改用全局声明保留类型提示:
declare var d3: typeof import('d3'); declare var nv: typeof import('nvd3'); // 其余业务逻辑保持不变
补充说明
该方案可解决d3多版本共存项目中的冲突问题,通过指定nvd3适配的d3版本,并全局暴露变量,确保nvd3能正确找到依赖的d3实例。
内容的提问来源于stack exchange,提问作者Jeb50
相关产品推荐
相关产品推荐

