如何配置Vite兼容D3.js v3.5.5?或修改源码适配?
解决d3.js v3.5.5在Vite环境下的兼容问题
问题回顾
d3.js v3采用旧的全局依赖写法,和Vite的ES模块系统不兼容,会出现global未定义、无法读取undefined的document属性,以及错误配置后出现的Cannot set property document of #<Window> which has only a getter问题。
方案一:仅修改Vite配置(无需改动d3源码)
在vite.config.js中添加以下配置:
export default { // 把global映射为浏览器环境的window对象 define: { global: 'window' }, // 直接引入d3的UMD适配版本,而非默认的CommonJS版本 resolve: { alias: { 'd3': 'd3/build/d3.min.js' } } }
原理:d3 v3的UMD版本原本就是为浏览器全局环境设计的,直接通过alias指向该版本,同时将global映射到window,既解决了global未定义的问题,又让d3能正确访问window.document。
方案二:修改d3源码适配模块环境
如果不想调整Vite配置,可以修改d3的源码,并用patch-package固化修改:
- 处理global未定义问题
找到node_modules/d3/index.js,将所有global替换为window:
var globals = {}; // Stash old global. if ("d3" in window) globals.d3 = window.d3; module.exports = require("./d3"); // Restore old global. if ("d3" in globals) window.d3 = globals.d3; else delete window.d3;
- 处理document无法读取问题
找到node_modules/d3/d3.js中的var d3_document = this.document;,将this改为window:
var d3_document = window.document;
- 执行
npx patch-package d3生成补丁,后续安装依赖时会自动应用修改。
错误配置说明
之前尝试的define: { global: {}, document: {} }会导致报错,因为window.document是只读属性,无法被赋值为空对象;同时空的global也无法提供d3需要的全局上下文,这完全偏离了正确的适配方向。
内容的提问来源于stack exchange,提问作者Leahcim
相关产品推荐
相关产品推荐

