d3 4.x 的 es6 模块导入失败

Posted

技术标签:

【中文标题】d3 4.x 的 es6 模块导入失败【英文标题】:es6 module import of d3 4.x fails 【发布时间】:2018-07-06 09:37:08 【问题描述】:

TL;DR:将 d3 导入 es6 模块的记录方法失败。这样做的正确方法是什么?我的猜测是文档假设我使用了解决这些问题的工作流程

详情: d3 4.x 的自述文件说:

D3 是使用 ES2015 模块编写的。使用 Rollup、Webpack 或您喜欢的捆绑器创建自定义捆绑包。要将 D3 导入 ES2015 应用程序,请从特定 D3 模块导入特定符号:

从“d3-scale”导入 scaleLinear;

或将所有内容导入命名空间(此处为 d3):

从“d3”导入*作为d3;

然而,当我yarn add d3 并使用 es6 脚本标签时,这不起作用:

<html>
<head>
  <title>D3</title>
</head>
<body>
  <script type="module">
    import * as d3 from "./node_modules/d3"
  </script>
</body>
</html>

加载模块脚本失败:服务器以“text/html”的非 javascript MIME 类型响应。根据 HTML 规范对模块脚本强制执行严格的 MIME 类型检查。

将导入替换为:

  import * as d3 from "./node_modules/d3/index.js"

..给出这个错误:

未捕获的类型错误:无法解析模块说明符“d3-array”

【问题讨论】:

2021,我也面临同样的问题。您(或其他任何人)是否能够找到(更简单的)解决方案? 【参考方案1】:

@jimmont 是正确的:由于“裸”导入,如果没有本地构建,导入 d3 包的模块形式将不起作用。这些可以通过 CDN 的 D3 使用解决,特别是 unpkg.com。这是故事。

事实证明 d3 使用 package.json 允许它从单个源(npm 本身)导出两种格式。为此,它使用模块:字段。

访问所有 d3 或子模块/repo(其中有 30 个!)的最简单方法是 unpkg:

回购的仪表板:https://unpkg.com/d3/ 当前的 umd/iife:https://unpkg.com/d3 所有模块的当前集合:https://unpkg.com/d3?module

要导入所有 d3:

import * as d3 from 'https://unpkg.com/d3?module'

导入子模块:

import * as selection from 'https://unpkg.com/d3-selection?module'

【讨论】:

【参考方案2】:

es6 和 es2015 模块不适用于 d3,因为 d3 已选择使用汇总。您会看到此错误,因为无法按照文件“./node_modules/d3/index.js”中的指定解析模块,该文件具有像export default as ascending from "./src/ascending"; 这样的行,其中缺少以“.js”结尾的真实文件名。所以换句话说,所有这些条目都被错误配置为不支持浏览器或 Nodejs 中的本机模块。

您可以使用汇总或使用脚本或手动进行所有文本替换。我使用 perl 单线,因为我不喜欢汇总,并且节点 8 和节点 10 之间的额外依赖关系中断。令人难以置信的是,这是必要的,但我也没有支持模块加载器的厨房水槽。

从“./node_modules/d3-something/index.js”导入 * as d3

它的内容类似于 export default as something from './src/thing'。因为这些文件不使用具有完整相对路径的本机支持的语法(它缺少实际的文件扩展名),所以如果没有汇总或进行这些更正,它将无法工作。多个受欢迎的项目都做出了同样的决定,需要额外的模块才能正常工作并放弃原生支持。

见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

【讨论】:

以上是关于d3 4.x 的 es6 模块导入失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ES6 模块导入来导入路径

ES6 模块,啥算作第一次导入?

ES6:从 URL 导入模块

如何模拟 ES6 模块的导入?

如何使用 es6 导入加载 emscripten 生成的模块?

将选项传递给 ES6 模块导入