更新 - 使用撰写本文时最新的节点的一些解决方法和咒语。
tsconfig
{
"include": [
"./src/**/*"
],
"exclude": [
"**/*.test.*",
"node_modules"
],
"ts-node": {
// Tell ts-node CLI to install the --loader automatically
"esm": true
},
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": [
"esnext"
],
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
package.json 不要使用
type: module
"engines": {
"node": ">=20.6.0"
},
"scripts": {
"dev": "node --watch -r ts-node/register src/server.ts",
----给未来的自己参考----
当我更新节点时,我所有的旧节点/ts 项目似乎都会抛出编译器错误。
有人可以推荐一个适用于 2024 年的参考节点+typescript 样板吗?
import
其他套餐看起来有道理吗?
我从这个 prisma 模板开始(他们非常了解 TS) https://github.com/prisma/prisma-examples/tree/latest/typescript/rest-express
但是一旦我添加一些包,它就会崩溃。
为了发展
ts-node-esm src/index.ts
> ReferenceError: exports is not defined in ES module scope
所以从
"type": "module"
中删除
package.json
错误 [ERR_REQUIRE_ESM]:require() ...
ts-node src/index.ts
> TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/dc/dev/hacks/kbxt/api/src/index.ts
也许节点版本破坏了一切?
$ nvm use --lts
Now using node v20.11.1 (npm v10.2.4)
$ ts-node src/index.ts
TypeError: Unknown file extension ".ts" for ...
npm i -g ts-node@latest
changed 20 packages in 391ms
➜ api git:(dc/vidgraph) ✗ ts-node -v
v10.9.1
$ node -v
v20.11.1
$ npx tsc
node_modules/@types/node/globals.d.ts:6:76 - error TS2792: Cannot find module 'undici-types'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
/// dozens of similar errors
$ npm run build
> [email protected] build
> tsc
node_modules/@types/node/globals.d.ts:6:76 - error TS2792: Cannot find module 'undici-types'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
好的,让我们将其添加到
tsconfig
"moduleResolution": "node",
宾果,好吧,现在我们至少可以编译了。
npm run dev
> [email protected] dev
> ts-node src/index.ts
TypeError: Unknown file extension ".ts" for /Users/dc/dev/hacks/kbxt/api/src/index.ts
我记得一些使用加载程序的巫术方法,让我们尝试一下
$ nodemon --exec 'ts-node-esm' src/index.ts
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/dc/dev/hacks/kbxt/api/src/index.ts
说要删除
type: module
但这不起作用。
困惑。
npm run build
> [email protected] build
> tsc
$ node dist/index.js
(node:57981) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/dc/dev/hacks/kbxt/api/dist/index.js:1
import express from "express";
^^^^^^
好的,所以把
type: module
放回去。
node dist/index.js
node:internal/modules/esm/resolve:264
throw new ERR_MODULE_NOT_FOUND(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/dc/dev/hacks/kbxt/api/dist/utils/Clog' imported from /Users/dc/dev/hacks/kbxt/api/dist/index.js
好的,所以我现在甚至无法运行
dist
编译的输出。
尝试添加一些
"moduleDirectories": [
"node_modules",
"src"
]
不。
$ node --loader ts-node/esm dist/index.js
(node:58752) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use `register()`:
--import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("ts-node/esm", pathToFileURL("./"));'
(Use `node --trace-warnings ...` to show where the warning was created)
node:internal/process/esm_loader:34
internalBinding('errors').triggerUncaughtException(
哦,那么也许 chalk 是那些激进的 ESM 软件包之一,只能与 JS 一起使用并搞砸打字稿项目?就像 cuid 和其他一些人一样。
npm uninstall chalk
npm i [email protected]
好的,明白了。
那么我们在 JS 生态系统中正处于这样一个阶段:某些包完全破坏了 typescript,而维护者更关注纯 JS 和 ESM 的未来?
我想我会把这个留在这里作为警告。
未来有更好的方法来解决这个问题吗? TS 团队是否需要基本上分叉主要软件包来维护与 typescript 一起使用的版本?
好吧...
$ npm run build
> [email protected] build
> tsc
$ node dist/index.js
(node:59510) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/dc/dev/hacks/kbxt/api/dist/index.js:1
import express from "express";
^^^^^^
SyntaxError: Cannot use import statement outside a module
at internalCompileFunction (node:internal/vm:77:18)
at wrapSafe (node:internal/modules/cjs/loader:1288:20)
at Module._compile (node:internal/modules/cjs/loader:1340:27)
at Module._extensions..js (node:internal/modules/cjs/loader:1435:10)
at Module.load (node:internal/modules/cjs/loader:1207:32)
at Module._load (node:internal/modules/cjs/loader:1023:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
at node:internal/main/run_main_module:28:49
Node.js v20.11.1
所以添加
type: module
回来并重试。
$ npm run build
> [email protected] build
> tsc
$ node dist/index.js
node:internal/modules/esm/resolve:264
throw new ERR_MODULE_NOT_FOUND(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/dc/dev/hacks/kbxt/api/dist/utils/Clog' imported from /Users/dc/dev/hacks/kbxt/api/dist/index.js
at finalizeResolution (node:internal/modules/esm/resolve:264:11)
at moduleResolve (node:internal/modules/esm/resolve:917:10)
at defaultResolve (node:internal/modules/esm/resolve:1130:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:396:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:365:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:240:38)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:85:39)
at link (node:internal/modules/esm/module_job:84:36) {
code: 'ERR_MODULE_NOT_FOUND',
url: 'file:///Users/dc/dev/hacks/kbxt/api/dist/utils/Clog'
}
Node.js v20.11.1
看起来我们已经更接近了,但 2024 年 TS 工作的海市蜃楼仍然遥不可及
Python 和快速 API 正在召唤...
在暂停时我
tsconfig.json
{
"compilerOptions": {
"target": "ESNext", //defines what sort of code ts generates
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": [
"esnext",
],
"esModuleInterop": true,
"moduleResolution": "node",
}
}
package.json
{
"name": "ts-test",
"version": "1.0.0",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "ts-node src/index.ts",
"build": "tsc"
},
"dependencies": {
"chalk": "^4.1.2",
"express": "4.18.3"
},
"devDependencies": {
"@types/express": "4.17.21",
"@types/node": "20.11.30",
"nodemon": "^3.1.0",
"ts-node": "^10.9.2",
"typescript": "5.4.3"
},
"moduleDirectories": [
"node_modules",
"src"
]
}
更新 - 使用撰写本文时最新的节点的一些解决方法和咒语。
使用节点20.6或更高版本 不要直接使用nodemon、ts-node esm/loader等,而是使用下面的 避免使用粉笔和其他仅限 ESM 的包装 tsconfig
{
"include": [
"./src/**/*"
],
"exclude": [
"**/*.test.*",
"node_modules"
],
"ts-node": {
// Tell ts-node CLI to install the --loader automatically
"esm": true
},
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": [
"esnext"
],
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}