开发者问题收集

使用 Typescript 和 ts-node 的 Node 脚本:无论配置和包类型如何,都无法导入任何内容

2023-04-27
8021

我有一个 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: trueesm: truemodule: CommonJS|ES2020|ESNext ...),但都没有成功。

问题

我必须做什么才能编写一个 用 Typescript 编写的 Node 脚本 ,我可以从命令行执行该脚本,该脚本 允许导入外部库和相对路径(也可以是 Typescript)?

谢谢!

2个回答

实际上,我终于能够通过正常导入使其工作。我遵循了以下步骤。我遵循了 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"
Unapedra
2023-04-27
  1. 通过运行命令 npm install typescript ts-node @types/node 安装必要的依赖项。

  2. 在项目的 根目录 中创建一个新的 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。

  1. 在项目的根目录中创建一个新的 src 目录,并在该目录中创建 TypeScript 文件。例如,创建一个名为 ma​​in.ts 的文件。

  2. 在 main.ts 中编写 TypeScript 代码。您可以使用 import 语句导入外部库和相对路径。

  3. 要从命令行运行脚本,可以使用 ts-node 命令。例如,要运行 main.ts,您可以使用命令 ts-node src/main.ts

您还可以将脚本添加到 package.json 文件中,以便更轻松地运行脚本。例如:

{
  "scripts": {
    "start": "ts-node src/main.ts"
  }
}
sundhar winston
2023-04-27