我在NodeJS中有一些导入问题。我想使用Typescript 3.8的新功能,例如私有字段:#myPrivateField
我不知道如何在我的班级中正确导入模块“ typescript”。我尝试了许多选择,但无法解决我的问题。
我的文件:
package.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模块以不同的方式进行导出。
例如,模块“打字稿”以export = ts
导出。
我也找到了这个参考,但是并没有太大帮助: https://www.typescriptlang.org/docs/handbook/modules.html
我的nodeJs版本是13.3.0,而我的打字稿版本是3.8.3 谢谢您的帮助
答案 0 :(得分:0)
ESM模块仍处于实验模式,有许多模块不支持它,例如使用module.exports
(CommonJS)而不是export
(ESM)。
您在这里的最佳选择是使用commonjs
模块并运行node
而没有任何标志。另外,type
中软件包的package.json
也必须为commonjs
。
回答问题“如何导入ESM模块” ...如果模块支持 ESM模块,则可以像平常一样使用import
:
import { something } from './something';
UPD::正如OP作者所提到的那样,要使私有字段正常工作,必须设置一个目标es2018
。其背后的原因是私有字段不是ES2015规范的一部分,因此您需要升级到受支持的最低目标。
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es2018"
}
答案 1 :(得分:0)
最后,良好的响应是:您需要commonjs
和es2018
才能在节点模块中使用打字稿#privateFields。
这是要使用的正确tsconfig.json:
{
"compileOnSave": false,
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es2018",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
}
}