node.js - 如何使用 NodeJS 13 和 Typescript 3.8 导入 esm 模块?
问题描述
我在 NodeJS 中的一些导入有问题。我想使用 Typescript 3.8 的新功能,比如私有字段:#myPrivateField
我不知道如何在课堂上正确导入模块“typescript”。我尝试了很多选择,但无法解决我的问题。
我的文件 :
包.json
{
"name": "test",
"scripts": {
"start": "tsc && node --experimental-modules --es-module-specifier-resolution=node main.js"
},
"dependencies": {
"@types/node": "^13.13.2",
"app-root-path": "^3.0.0",
"fs-extra": "^9.0.0",
"tsutils": "^3.17.1"
},
"devDependencies": {
"ts-node": "~8.3.0",
"typescript": "^3.8.3"
},
"type": "module"
}
tsconfig.json
{
"compilerOptions": {
"lib": [
"ESNext",
"es2016",
"dom",
"es5"
],
"module": "esnext",
"moduleResolution": "Node",
"sourceMap": true,
"target": "es6",
"typeRoots": [
"node_modules/@types"
]
}
}
main.ts
// import ts = require("typescript");
import * as ts from "typescript";
export class Main {
node: ts.Node;
#test = 'zzz';
constructor() {}
process(): void {
ts.forEachChild(this.node, function cb() {
});
console.log('#test', this.#test);
}
}
const main = new Main();
main.process();
使用此代码,当我运行时npm run start
,出现错误TypeError: ts.forEachChild is not a function
如果没有它的行,ts.forEachClid()
则正确记录私有字段#test 的值。
如果我尝试替换import * as ts from "typescript";
为import ts = require("typescript");
,我有错误TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead
当然,我在 tsconfig.json 和 package.json 中尝试了很多更改(使用 `"type" = "module"),但无法解决这个问题。
我什至尝试用 替换"module": "esnext"
,"module": "commonjs"
但我有一个错误exports is not defined
。
备注:这不是特定于模块“打字稿”。我对“fs-extra”等其他模块也有同样的问题,这些模块以与大多数经典 NodeJS 模块不同的方式进行导出。
例如,模块“typescript”导出为export = ts
.
我也找到了这个参考,但它对我没有多大帮助: https ://www.typescriptlang.org/docs/handbook/modules.html
我的 nodeJs 版本是 13.3.0,我的 typescript 版本是 3.8.3 感谢您的帮助
解决方案
ESM 模块仍处于实验模式,有很多模块不支持它,例如使用module.exports
(CommonJS)而不是export
(ESM)。
您最好的选择是使用commonjs
模块并在node
没有任何标志的情况下运行。此外,type
包装中的package.json
必须也是commonjs
如此。
回答您的问题“如何导入 ESM 模块”... 如果模块确实支持ESM 模块,您可以import
像往常一样使用:
import { something } from './something';
UPD:正如 OP 作者所提到的,要使私有字段起作用,必须设置一个 target es2018
。这背后的原因是私有字段不是 ES2015 规范的一部分,您需要升级到最小支持目标才能做到这一点。
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es2018"
}
推荐阅读
- node.js - Openshift平台上的Nodejs oracle Db连接
- javascript - Angular 10 升级 - 修复 CommonJS 或 AMD 依赖项可能导致优化救助
- javascript - 内联编辑器中的对话流捕获实体
- php - SQLSTATE [23000]:违反完整性限制:1062 'mail@mail.com' 'users_email_unique' 键的重复条目
- php - Alpha vantage API 不适用于 NSE,而同一查询为外国股票提供输出
- java - RefreshAheadCache 不调用 @cacheable 注释方法
- python - 如何为 Tacker 分解实现 mode-k 乘积 Python?
- smtp - SMTP 错误:DATA END 命令失败:550 5.7.1 客户端无权作为此发件人发送
- c# - 多个 RDLC 到单独页面上的单个 word 文档
- python - 在嵌套的 for 循环中过滤子数据框