为了将 typescript 更新为更现代的标准(特别是像 nanoid 这样的库不再支持 commonjs 导出),我们正在尝试让
ts-node-dev
库能够导出到 ecmascript 模块。
配置如下:
--- 包.json
{
"name": "test002",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"start": "NODE_ENV=production node ./javascript/app-ts.mjs",
"build": "tsc && rm -rf build && rsync -avq --exclude 'build' --exclude '.gitignore' --exclude 'test' --exclude 'jest.config.js' --exclude '.idea' --exclude '__mocks__' . ./build",
"start-test": "node src/bin/www.mjs",
"debug": "NODE_ENV=development tsnd --respawn src/app-ts.mts"
},
// ..
--- tsconfig.json
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
"target": "es2019", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "NodeNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"lib": ["es2015","es2019","es2020"], /* Specify library files to be included in the compilation. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "javascript", /* Redirect output structure to the directory. */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
/* Module Resolution Options */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"exclude": [
".idea",
"build",
"node_modules",
"typings/globals",
"typings/modules",
"test"
],
"include": [
"src/**/*"
],
"files": [
"src/global.d.ts",
"src/types.d.ts"
]
}
如果通过
tsc
进行编译(或通过 npm run build
也将所有文件复制到位),则项目运行良好。
但是运行
npm run debug
会出现此错误:
19:06:16 ts-node-dev ver. 2.0.0 (using ts-node ver. 10.9.1, typescript ver. 5.1.6)
/home/paul/Documents/webasupport/spiderwebplugins/bff2/src/app-ts.mts:6
import * as http from "http";
^^^^^^
SyntaxError: Cannot use import statement outside a module
at internalCompileFunction (node:internal/vm:73:18)
at wrapSafe (node:internal/modules/cjs/loader:1153:20)
at Module._compile (node:internal/modules/cjs/loader:1197:27)
at Module._compile (/home/paul/Documents/webasupport/spiderwebplugins/bff2/node_modules/source-map-support/source-map-support.js:568:25)
at Module._extensions..js (node:internal/modules/cjs/loader:1287:10)
at require.extensions..jsx.require.extensions..js (/tmp/ts-node-dev-hook-34321391877988616.js:114:20)
at Object.nodeDevHook [as .js] (/home/paul/Documents/webasupport/spiderwebplugins/bff2/node_modules/ts-node-dev/lib/hook.js:63:13)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Function.Module._load (node:internal/modules/cjs/loader:938:12)
at Module.require (node:internal/modules/cjs/loader:1115:19)
我也尝试过手动:
tsnd --respawn src/app-ts.mts
或者更基本的方法:
ts-node src/app-ts.mts
后者给出了错误:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".mts" for /home/paul/Documents/webasupport/spiderwebplugins/bff2/src/app-ts.mts
at new NodeError (node:internal/errors:405:5)
at Object.getFileProtocolModuleFormat [as file:] (node:internal/modules/esm/get_format:99:9)
at defaultGetFormat (node:internal/modules/esm/get_format:142:36)
at defaultLoad (node:internal/modules/esm/load:91:20)
at DefaultModuleLoader.load (node:internal/modules/esm/loader:263:26)
at DefaultModuleLoader.moduleProvider (node:internal/modules/esm/loader:179:22)
at new ModuleJob (node:internal/modules/esm/module_job:63:26)
at DefaultModuleLoader.#createModuleJob (node:internal/modules/esm/loader:203:17)
at DefaultModuleLoader.getJobFromResolveResult (node:internal/modules/esm/loader:156:34)
at DefaultModuleLoader.getModuleJob (node:internal/modules/esm/loader:141:17) {
code: 'ERR_UNKNOWN_FILE_EXTENSION'
}
这似乎表明 ts-node 没有作为模块运行。 (所有谷歌结果都告诉我从 package.json 中删除
"type": "module"
,但重点是让它发挥作用。
我看到的最后一个选项是向 ts-node 添加
--esm
选项。但添加似乎有完全相同的错误。
如何使
ts-node
以及相应的 ts-node-dev
与 esm 模块一起使用,或者是否有其他方法可以在打字稿中进行热重载?
我在使用 ESM 的 ts-node-dev 时也遇到了问题。为了使其正常工作,我将 nodemon 与 ts-node 一起使用。这是我的配置:
//tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"outDir": "dist",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true
},
"ts-node": {
"esm": true
},
"exclude": ["node_modules", "./*.ts", "__test__"]
}
//package.json
{
...
"type": "module",
"scripts": {
"build": "tsc",
"test": "node --experimental-vm-modules node_modules/.bin/jest",
"dev": "nodemon src/index.ts",
"start": "node dist/index.js"
},
"devDependencies": {
"@types/jest": "^29.5.3",
"@types/node": "^20.4.8",
"jest": "^29.6.2",
"nodemon": "^3.0.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.1.6"
}
...
}
查看此问题以了解更多详细信息。