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

问题描述 投票:0回答:2

我有一个 React Typescript 项目,其中有多个共享结构的文件。代码很相似,但在某些点上它们之间有很大不同,并且必须复制粘贴文件并更改一些信息来创建其中一些新文件是很常见的。

我想创建一个 Node 脚本,要求用户提供一些输入,并自动执行此操作。因为我不想为此创建一个包(因为它是我当前项目中的一个简单脚本),所以我只是创建了一个名为

scripts
的文件夹并将其放在那里。

所以,项目结构如下:

- node_modules/
- scripts/
  - myScript/
    - helpers/
    - index.ts
    - package.json
- ...
- src/
- tsconfig.json
- package.json

为了能够执行 Typescript,我安装了

ts-node
库,并且通过主项目的
npm script
中的
package.json
执行此脚本:

"run-script": "ts-node ./scripts/myScript"

这个项目的

src
文件夹中已经有代码,而这个
scripts
文件夹是一个补充,不属于主应用程序的代码,这就是为什么我将它单独放在一个外部文件夹中,因为它更像是一个团队中开发人员的帮助工具。

问题

每当我尝试导入时,都会收到此错误:

throw new ERR_MODULE_NOT_FOUND(
          ^
CustomError: Cannot find module ...

如果我对包使用动态导入并在

esModuleInterop
文件中设置
tsconfig
,则一切正常。但一旦我尝试导入具有相对路径的方法,它就会中断:

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)?

谢谢!

javascript node.js typescript npm-scripts ts-node
2个回答
0
投票

实际上我已经能够通过正常导入使其最终工作。我遵循的步骤。我遵循了 ts-node esm:

的文档
  • 安装
    ts-node
    软件包。
  • package.json
    文件夹内创建一个
    scripts
    并设置
    "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';
  • ts-node
    中使用
    package.json
    运行节点脚本:
"run-my-script": "ts-node ./scripts/myScript"

0
投票
  1. 通过运行命令 npm install typescript ts-node @types/node 安装必要的依赖项。

  2. 在项目的 root 中创建一个新的 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 文件。例如,创建一个名为 main.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"
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.