Nodejs、TypeScript、ts-node-dev 和顶级等待
Nodejs, TypeScript, ts-node-dev & top-level await
在需要顶级等待之后,我现在已经花了一个小时来寻找新错误的解决方案。到目前为止我尝试过的所有其他方法都没有解决错误,例如将 "type": "module"
添加到 package.json 文件。
启动服务时的错误信息是Cannot use import statement outside a module
。
如果我将更改 "module": "ESNext",
恢复为 "module": "commonjs",
,它工作正常(除了必须删除 await 关键字并以某种方式重构以在没有 await 的情况下工作)。
此外,我使用ts-node-dev来运行可以在package.json文件中看到的服务。
- 我需要的新包是kafkajs。
- 节点版本:v14.9.0
- TypeScript 版本:4.0
package.json
{
"name": "",
"version": "1.0.0",
"description": "microservice",
"main": "src/index.ts",
"author": "",
"type": "module",
"license": "MIT",
"scripts": {
"dev": "NODE_ENV=development tsnd --respawn --files src/index.ts",
"prod": "NODE_ENV=production tsnd --respawn --transpile-only --files src/index.ts",
"test": "mocha --exit -r ts-node/register tests/**/*.spec.ts",
"eslint": "eslint src/**/*.ts"
},
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"outDir": "dist",
"sourceMap": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"ts-node": {
"files": true,
"transpileOnly": true
},
"include": ["src/**/*.ts", "declariations/**.d.ts"],
"exclude": ["node_modules", ".vscode"]
}
TL;DR:不要将 ECMAScript 模块与 ts-node 或 ts-node-dev 一起使用(目前);只需重构顶层 await out
今天我掉进了同一个兔子洞,从无害的错误开始:
Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
因此,我倾向于编辑我的 tsconfig.json
并将 module
设置为 esnext
,这反过来又迫使我将 moduleResolution
设置为 node
最后将 type: module
添加到我的 package.json
。我没有意识到(IMO 他们不应该在错误消息中建议这一点——你可以简单地重构顶层等待),这将 NodeJS 的模块解析策略从 CommonJS 切换到 ESM。这实际上是一件大事,原因有很多:
- ESM support is still experimental in ts-node
- Mixing CJS and ESM modules may lead to problems
- There are open issues with ESM support in NodeJS itself
我觉得此时(2020 年 12 月)NodeJS 生态系统仍在从经典的 CommonJS 模块向新的 ECMAScript 模块过渡。因此,其他技术(如 ts-node 或 ts-node-dev)也在转型,支持可能不稳定。我的建议是坚持使用 CommonJS,直到尘埃落定,这些东西开箱即用。
我知道,这个问题已经很老了,但是对于像我今天早些时候一样路过这个问题的人来说:
我刚刚设法让它工作。不是直接使用 ts-node-dev
,而是使用 nodemon
和 ts-node
.
的组合
你需要安装nodemon
和ts-node
然后,假设你的入口文件是src/index.ts
,你可以使用这个命令:
nodemon --ext ts --loader ts-node/esm --experimental-specifier-resolution node src
(使用 Node v16.13.0 测试)
这是我弄明白的关键 post:https://github.com/TypeStrong/ts-node/issues/1007
在需要顶级等待之后,我现在已经花了一个小时来寻找新错误的解决方案。到目前为止我尝试过的所有其他方法都没有解决错误,例如将 "type": "module"
添加到 package.json 文件。
启动服务时的错误信息是Cannot use import statement outside a module
。
如果我将更改 "module": "ESNext",
恢复为 "module": "commonjs",
,它工作正常(除了必须删除 await 关键字并以某种方式重构以在没有 await 的情况下工作)。
此外,我使用ts-node-dev来运行可以在package.json文件中看到的服务。
- 我需要的新包是kafkajs。
- 节点版本:v14.9.0
- TypeScript 版本:4.0
package.json
{
"name": "",
"version": "1.0.0",
"description": "microservice",
"main": "src/index.ts",
"author": "",
"type": "module",
"license": "MIT",
"scripts": {
"dev": "NODE_ENV=development tsnd --respawn --files src/index.ts",
"prod": "NODE_ENV=production tsnd --respawn --transpile-only --files src/index.ts",
"test": "mocha --exit -r ts-node/register tests/**/*.spec.ts",
"eslint": "eslint src/**/*.ts"
},
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"outDir": "dist",
"sourceMap": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"ts-node": {
"files": true,
"transpileOnly": true
},
"include": ["src/**/*.ts", "declariations/**.d.ts"],
"exclude": ["node_modules", ".vscode"]
}
TL;DR:不要将 ECMAScript 模块与 ts-node 或 ts-node-dev 一起使用(目前);只需重构顶层 await out
今天我掉进了同一个兔子洞,从无害的错误开始:
Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
因此,我倾向于编辑我的 tsconfig.json
并将 module
设置为 esnext
,这反过来又迫使我将 moduleResolution
设置为 node
最后将 type: module
添加到我的 package.json
。我没有意识到(IMO 他们不应该在错误消息中建议这一点——你可以简单地重构顶层等待),这将 NodeJS 的模块解析策略从 CommonJS 切换到 ESM。这实际上是一件大事,原因有很多:
- ESM support is still experimental in ts-node
- Mixing CJS and ESM modules may lead to problems
- There are open issues with ESM support in NodeJS itself
我觉得此时(2020 年 12 月)NodeJS 生态系统仍在从经典的 CommonJS 模块向新的 ECMAScript 模块过渡。因此,其他技术(如 ts-node 或 ts-node-dev)也在转型,支持可能不稳定。我的建议是坚持使用 CommonJS,直到尘埃落定,这些东西开箱即用。
我知道,这个问题已经很老了,但是对于像我今天早些时候一样路过这个问题的人来说:
我刚刚设法让它工作。不是直接使用 ts-node-dev
,而是使用 nodemon
和 ts-node
.
你需要安装nodemon
和ts-node
然后,假设你的入口文件是src/index.ts
,你可以使用这个命令:
nodemon --ext ts --loader ts-node/esm --experimental-specifier-resolution node src
(使用 Node v16.13.0 测试)
这是我弄明白的关键 post:https://github.com/TypeStrong/ts-node/issues/1007