如果没有定义如何添加全局变量

问题描述 投票:0回答:1

当 d3.js 迁移到版本 4 时,对 Api 进行了重大重写,并对模块化打包进行了更改。

我不想升级到 d3.js 版本 4,但我必须使用 Vite 重写项目的 React/redux Web 应用程序部分,而 d3.js 版本 3 及其对 global 的使用与Vite 使用的 JavaScript 模块化系统。

我收到的错误是“global”未定义,并且 d3.js 版本 3 使用“global”。

这就是它所说的

node_modules/d3/index.js (index.js:4:13)

var globals = {};

// Stash old global.
if ("d3" in global) globals.d3 = global.d3;

module.exports = require("./d3");

// Restore old global.
if ("d3" in globals) global.d3 = globals.d3; else delete global.d3;

因此,我在 d3/index.js 文件中注释掉了对 global 的引用,看看会发生什么,并且我得到了一个类似的属性,“无法读取未定义的属性(文档)”这是源代码

var d3_document = this.document;
function d3_documentElement(node) {
  return node && (node.ownerDocument || node.document || node).documentElement;
}

我猜这与版本 4 中向模块化 d3 的转变有关,但当我不将其与 Vite.js 一起使用时,d3.js 版本 3.5.5 工作正常。例如,如果我只是在 index.html 文件中获取它并使用 http 服务器运行它。

问题:有没有办法配置Vite.js使其与d3.js 3.5.5版本一起使用?或者我可以更改 d3.js 3.5.5 版本的源代码以使其在 Vite.js 上运行吗?

更新

我将其添加到 Vite.config.js 中

  define: {
    global: {},
    document: {}
  }

现在 Vite 抱怨无法在

document
 上设置属性 
#<Window>.

3env.ts:24  Uncaught TypeError: Cannot set property document of #<Window> which has only a getter

这个 StackOverflow 问题有帮助,但它没有解释何时“文档”未定义并且无法在 Window 上“设置”。

可能不相关,但这是 unpkg.com 上 d3 版本 3.5.5 的源代码 d3版本3.5.5`

这是 unpkg.com 上 d3 版本 4 的源代码 d3 版本 4

javascript reactjs vite
1个回答
0
投票

为了让D3.js 3.5.5版本兼容Vite,您需要解决“全局未定义”问题,并在Vite环境中正确管理文档对象。这是一个逐步解决方案:

  1. Polyfill 全局对象:在 Vite 中,默认没有定义全局。创建一个polyfill以全局引用window对象。
// init.js
window.global ||= window;

在主文件的开头导入此脚本。

  1. 修改Document对象的D3.js源码:由于Vite中的Window对象无法设置document,所以修改D3.js源码,将其绑定到window上。将 D3.js 代码包装在 IIFE 中:
(function() {
    // D3.js code
}).call(window);

对于 vite 配置请谨慎使用 vite.config.js 中的变量定义选项。根据vite的官方文档,建议仅用于常量。像 global 这样的变量应该被填充或填充。

© www.soinside.com 2019 - 2024. All rights reserved.