使用 Typescript 和 ts-node 的 Node 脚本:无论配置和包类型如何,都无法导入任何内容
我有一个 React Typescript 项目,它有多个共享结构的文件。代码相似,但在某些方面有很大不同,并且经常需要复制粘贴文件并更改一些信息来创建其中一些新文件。
我想创建一个 Node 脚本,要求用户输入一些信息,然后自动执行此操作。因为我不想为此创建一个包(因为它是我当前项目中的一个简单脚本),所以我只创建了一个名为
scripts
的文件夹并将其放在那里。
因此,项目结构如下:
- node_modules/
- scripts/
- myScript/
- helpers/
- index.ts
- package.json
- ...
- src/
- tsconfig.json
- package.json
为了能够执行 Typescript,我安装了
ts-node
库,并且我正在通过主项目的
package.json
中的
npm script
执行此脚本:
"run-script": "ts-node ./scripts/myScript"
此项目的
src
文件夹中已经有代码,而这个
scripts
文件夹是不属于主应用程序代码的补充,这就是为什么我将其放在外部文件夹中,因为它更像是开发人员的帮助工具。团队。
问题
每当我尝试导入时,都会收到此错误:
throw new ERR_MODULE_NOT_FOUND(
^
CustomError: Cannot find module ...
如果我对包使用动态导入并在我的
tsconfig
文件中设置
esModuleInterop
,则一切都正常。但是,当我尝试使用相对路径导入方法时,它就会中断:
const inquirer = (await import('inquirer')).default;
const fs = (await import('fs-extra')).default;
const { getCommonPath } = await import('./helpers/getCommonPath');
Error [ERR_MODULE_NOT_FOUND]: Cannot find module ...
我认为这可能与目录路径有关,但如果我在导入中使用
__dirname
,它会告诉我由于路径的格式不允许这样做。
如果我尝试改用非动态导入,则会收到以下错误:
(node:106220) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
但如果我这样做,则会收到此错误:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for ...
然后我认为这与
ts-node
配置有关,我读到使用 ts-node-esm。但如果我这样做,则第一个错误会再次出现。我还尝试了
ts-node
的多种配置(
esModuleInterop: true
、
esm: true
、
module: CommonJS|ES2020|ESNext
...),但都没有成功。
问题
我必须做什么才能编写一个 用 Typescript 编写的 Node 脚本 ,我可以从命令行执行该脚本,该脚本 允许导入外部库和相对路径(也可以是 Typescript)?
谢谢!
实际上,我终于能够通过正常导入使其工作。我遵循了以下步骤。我遵循了 ts-node esm 的文档:
-
安装
ts-node
包。 -
在
scripts
文件夹中创建package.json
并设置"type": "module"
。 -
将以下配置添加到您的
tsconfig.json
:
"ts-node": {
"transpileOnly": true,
"compilerOptions": {
"module": "ESNext",
"esModuleInterop": true
},
"esm": true // <--- this is the most important part
},
"compilerOptions": {...}
- 将文件扩展名 (.ts) 添加到您的相对导入。 Eslint-TS 会报错,但这是让它工作的唯一方法(否则它将找不到模块):
import fs from 'fs-extra';
import { getSrcPath } from './helpers/getSrcPath.ts';
-
使用
package.json
中的ts-node
运行节点脚本:
"run-my-script": "ts-node ./scripts/myScript"
-
通过运行命令 npm install typescript ts-node @types/node 安装必要的依赖项。
-
在项目的 根目录 中创建一个新的 tsconfig.json 文件,其中包含以下内容:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"esModuleInterop": true,
"outDir": "./dist",
"rootDir": "./src",
"resolveJsonModule": true,
"sourceMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
此配置文件告诉 TypeScript 如何将源代码编译为 JavaScript。
-
在项目的根目录中创建一个新的 src 目录,并在该目录中创建 TypeScript 文件。例如,创建一个名为 ma​​in.ts 的文件。
-
在 main.ts 中编写 TypeScript 代码。您可以使用 import 语句导入外部库和相对路径。
-
要从命令行运行脚本,可以使用 ts-node 命令。例如,要运行 main.ts,您可以使用命令 ts-node src/main.ts 。
您还可以将脚本添加到 package.json 文件中,以便更轻松地运行脚本。例如:
{
"scripts": {
"start": "ts-node src/main.ts"
}
}