升级到 Angular 8 后出现 d3.js 运行时错误

Posted

技术标签:

【中文标题】升级到 Angular 8 后出现 d3.js 运行时错误【英文标题】:d3.js runtime error after upgrade to Angular 8 【发布时间】:2019-10-17 10:01:54 【问题描述】:

我正在尝试将我的 Angular 6 应用程序升级到 Angular 8。我的代码可以编译,但我立即收到运行时错误“d3.js:8 Uncaught TypeError: Cannot read property 'document' of undefined”。

d3.js 中失败的行是var d3_document = this.document;。这让我相信 Angular 8 在严格模式下运行 d3.js。我有最新版本的d3节点模块("d3": "3.5.17"),显然不支持严格模式;我的理解是“this”应该引用窗口​​对象,但在严格模式下不起作用。

我知道 Angular 8 现在使用 dart-sass 而不是 node-sass,据说后者更严格。我确实尝试安装 node-sass 来使用它而不是 dart-sass(按照升级文档的建议),但我很确定这与 sass 无关。

我会注意到我的一些其他包需要更新,因为它们依赖于 Angular 6 的包,但我看不出这会如何影响他的 d3 错误。

我也尝试在我的 tsconfig.json 文件中明确说出 "noImplicitUseStrict": false,,但收到了同样的错误。我也尝试过"noImplicitUseStrict": true,,但没有成功。

我参考了这篇解决相同错误的堆栈溢出帖子:D3.js : Uncaught TypeError: Cannot read property 'document' of undefined,以及参考的解决方案: https://***.com/questions/33821312/how-to-remove-global-use-strict-added-by-babel;但是我很难将这些应用于我的情况,因为我正在处理一个 Angular 项目并且不确定 babel 是否适用或如何修改 babel 选项。

完全错误:

d3.js:8 Uncaught TypeError: Cannot read property 'document' of undefined
    at d3.js:8
    at Object../node_modules/d3/d3.js (d3.js:9554)
    at __webpack_require__ (bootstrap:83)
    at Module../dist/core-services/fesm2015/core-services.js (core-services.js:1)
    at __webpack_require__ (bootstrap:83)
    at Module../src/app/app.component.ts (main-es2015.js:22262)
    at __webpack_require__ (bootstrap:83)
    at Module../src/app/app.module.ts (app.component.ts:21)
    at __webpack_require__ (bootstrap:83)
    at Module../src/main.ts (main.ts:1)
(anonymous) @   d3.js:8
./node_modules/d3/d3.js @   d3.js:9554
__webpack_require__ @   bootstrap:83
./dist/core-services/fesm2015/core-services.js  @   core-services.js:1
__webpack_require__ @   bootstrap:83
./src/app/app.component.ts  @   main-es2015.js:22262
__webpack_require__ @   bootstrap:83
./src/app/app.module.ts @   app.component.ts:21
__webpack_require__ @   bootstrap:83
./src/main.ts   @   main.ts:1
__webpack_require__ @   bootstrap:83
0   @   main.ts:17
__webpack_require__ @   bootstrap:83
checkDeferredModules    @   bootstrap:45
webpackJsonpCallback    @   bootstrap:32
(anonymous) @   main-es2015.js:1

预计没有错误。有没有办法指定我不希望这个节点模块在严格模式下运行?

【问题讨论】:

D3.js : Uncaught TypeError: Cannot read property 'document' of undefined的可能重复 嗨@Reactgular,我确实看到了那篇文章,并试图将其应用于我的情况。我不知道如何修改 Angular 项目中的 babel 选项。 【参考方案1】:

我从昨天早上开始就遇到了同样的问题,但我现在已经解决了。

在我的 package.json 中,我使用以下包:

"d3": "^3.5.17",
"ng2-nvd3": "^2.0.0",
"nvd3": "^1.8.6"

这里真正的问题是 D3 库还没有为 ES2015/ES6 做好准备。

因此,要解决此问题,您需要更改 Angular 解决方案的 tsconfig.json 文件中的 2 项。

module = es2015 而不是 esnext

target = es5 而不是 es2015

所以完整的 tsconfig.json 应该是这样的:


  "compileOnSave": false,
  "compilerOptions": 
    "baseUrl": "./",
    "importHelpers": true,
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  

要查看实际的图表,请在此处查看我的教程: http://www.exodus-cloud.co.uk/tutorials/angular-charting-nvd3

【讨论】:

谢谢你!我相应地更新了目标和模块,现在有了一个工作应用程序。将模块设置为 es2015 时收到此错误,因此我最终将其设置为 commonjs。 error TS1323: Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'. 对我来说,将目标从“es2015”更改为“es5”就足够了。 这不是解决方案,而是一种解决方法。使用 Angular 7,可以定位 es2016/es2017,这显然适用于 d3。现在升级到不再工作的 Angular 8 之后。这要么意味着 Angular 7 没有在编译中包含 d3,但现在在 v8 中包含,要么意味着 Angular 8 存在问题。 我担心这些变通办法的副作用... Angular 10 有什么合适的解决方案吗?【参考方案2】:

我能够通过在 angular.json 的“脚本”字段中包含 d3 来使其工作。

【讨论】:

以上是关于升级到 Angular 8 后出现 d3.js 运行时错误的主要内容,如果未能解决你的问题,请参考以下文章

角度从 8 升级到 9 - 纱线不兼容错误

Renderer2 在使用 d3 js - Angular 4 时不渲染 SVG 元素

从 Angular 7 升级到 Angular 8 后,我的管道测试停止工作:TypeError: undefined is not iterable

将 D3.js 导入 Angular 2 应用程序的正确方法

在 Angular2 中使用 d3.js

d3.js:在 Angular 应用程序和 node.js 上运行相同的代码