无法将d3-geo包导入到Node.js TypeScript项目中。

5

我正在尝试编写代码来测试特定的经纬度坐标是否可以在各种GeoJSON Feature中找到。

如果我这样做:

import d3 from 'd3-geo'; // or: import * as d3 from 'd3-geo' // makes no difference

console.log(d3.geoContains);

运行命令:node --require ts-node/register app.ts

当我运行时,出现以下错误:

Error [ERR_REQUIRE_ESM]: 在 /Users/kshetline/temp/geo/app.ts 中,不能使用 require() 导入 ES 模块 /Users/kshetline/temp/geo/node_modules/d3-geo/src/index.js 。 取而代之,在 /Users/kshetline/temp/geo/app.ts 中将 index.js 的 require 更改为动态 import(),它在所有 CommonJS 模块中都可用。 at Object. (/Users/kshetline/temp/geo/app.ts:6:34) at Module.m._compile (/Users/kshetline/temp/geo/node_modules/ts-node/dist/index.js:735:29) at Object.require.extensions. [as .ts] (/Users/kshetline/temp/geo/node_modules/ts-node/dist/index.js:737:16) { code: 'ERR_REQUIRE_ESM' }

因此,我尝试按照错误消息建议使用 import()

import('d3-geo').then(d3 => console.log(d3.geoContains));

...这仅给我一个更短但类似的错误信息:

错误[ERR_REQUIRE_ESM]:从/Users/kshetline/temp/geo/app2.ts调用ES模块 /Users/kshetline/temp/geo/node_modules/d3-geo/src/index.js 的require()不受支持。请改用可在所有CommonJS模块中使用的动态import()来替换/Users/kshetline/temp/geo/app2.ts中index.js的require。
发生位置:/Users/kshetline/temp/geo/app2.ts:21:43 {code: 'ERR_REQUIRE_ESM'}

我尝试了不同的模块类型和目标在tsconfig.json中,但这没起到帮助作用。下面是我创建的简化测试项目的tsconfig.json:

{
  "compilerOptions": {
    "target": "es2021",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}

这里是 package.json 文件:

{
  "name": "geo",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "author": "",
  "license": "MIT",
  "dependencies": {
    "d3-geo": "^3.0.1"
  },
  "devDependencies": {
    "@types/d3-geo": "^3.0.2",
    "ts-node": "^10.4.0",
    "typescript": "^4.5.5"
  }
}

我从未遇到过一个npm库,让我在尝试进行简单导入时遇到如此多的麻烦。我可以在普通JavaScript中使其工作,但即使是这样也必须使用动态import(),这是一种令人恼火的消费库的方式。

有什么更好的方法可以让它更好地工作吗?

2个回答

3

我还没有一个令人满意的答案,但至少我有一个愚蠢的解决方法。我在我的tsconfig.json文件中设置了"allowJs": true,并添加了一个名为module-bridge.cjs的 JavaScript 文件,内容如下:

module.exports = {
  d3_geo: async function () { return import('d3-geo'); }
};

然后我把这个代码放到了我的 TypeScript 代码里:

import { d3_geo } from './module-bridge.cjs';

// ...

const geoContains = (await d3_geo()).geoContains;

你会认为我可以直接在我的 TypeScript 代码中使用 import('d3-geo'),但这会导致编译错误。

这很糟糕,但它运行得很好。谢谢。 - Joshua
谢谢,这个变通方法对我起作用了。我也想不出其他让它工作的办法! - Luke Belbina

0

对我来说,将版本降级到2.0.2并通过导入解决了问题。

import * as d3Geo from 'd3-geo';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接