You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在npm TypeScript包中编写支持顶级await的工具脚本

问题描述

我正在开发TypeScript React项目,想自动化新组件的文件夹和文件创建流程——用TypeScript写工具脚本保证类型安全,依赖能通过npm轻松安装,还想用await语法(最好是顶级await)。希望尽量不修改主tsconfig.json,只对package.json的scripts和devDependencies做最小改动。

现有文件结构:

.
├── package.json
├── scripts
│   └── createFile.ts
├── src
│   └── components
└── tsconfig.json

package.json内容:

{
  "name": "utilscript",
  "version": "1.0.0",
  "scripts": {
    "create-file": "ts-node scripts/createFile.ts"
  },
  "devDependencies": {
    "@types/node": "^18.15.5",
    "ts-node": "^10.9.1",
    "typescript": "^5.0.2"
  }
}

主tsconfig.json内容:

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": [
    "src"
  ]
}

scripts/createFile.ts内容:

import { writeFile, mkdir } from 'node:fs/promises'

const componentName = 'Test' // 最终会改成命令行参数

await mkdir(`./src/components/${componentName}`)
await writeFile(`./src/components/${componentName}/index.tsx`, '')

遇到的错误

  1. 执行npm run create-file时,TS报错顶级await不允许:
scripts/createFile.ts:5:1 - error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', or 'nodenext', and the 'target' option is set to 'es2017' or higher.

5 await mkdir(`./src/components/${componentName}`)
  ~~~~~
scripts/createFile.ts:6:1 - error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', or 'nodenext', and the 'target' option is set to 'es2017' or higher.

6 await writeFile(`./src/components/${componentName}/index.tsx`, '')
  ~~~~~
  1. 把主tsconfig.json的module改成esnext、target改成es2017后,执行命令出现模块错误:
(node:66146) 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/rpmccarter/Documents/codes/misc/stackOverflow/utilScript/scripts/createFile.ts:1
import { writeFile, mkdir } from 'node:fs/promises';
^^^^^^

SyntaxError: Cannot use import statement outside a module
  1. 在package.json添加"type": "module"后,又出现文件扩展名错误:
TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /Users/rpmccarter/Documents/codes/misc/stackOverflow/utilScript/scripts/createFile.ts

解决方案

方案1:给ts-node指定临时编译参数(无需修改主tsconfig)

直接在package.json的scripts里给ts-node追加参数,临时覆盖编译配置以支持顶级await,同时处理ES模块兼容:

"scripts": {
  "create-file": "ts-node --esm --compiler-options '{\"module\":\"esnext\",\"target\":\"es2017\"}' scripts/createFile.ts"
}
  • --esm:让ts-node以ES模块模式运行,避免import语法报错
  • --compiler-options:临时设置满足顶级await要求的编译选项,不改动主tsconfig

方案2:给scripts文件夹单独配置tsconfig

如果觉得命令行参数太长,可在scripts目录下新建tsconfig.scripts.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "module": "esnext",
    "target": "es2017"
  },
  "include": ["."]
}

然后修改package.json的scripts:

"scripts": {
  "create-file": "ts-node --project scripts/tsconfig.scripts.json --esm scripts/createFile.ts"
}

这种方式既复用主配置,又单独给脚本设置所需编译选项,不影响主项目的tsconfig。

方案3:用tsx替代ts-node(最简洁)

tsx是一个无需额外配置就能直接运行TS/TSX文件的工具,天然支持ES模块和顶级await:

  1. 安装tsx:
npm install -D tsx
  1. 修改package.json的scripts:
"scripts": {
  "create-file": "tsx scripts/createFile.ts"
}

无需修改任何tsconfig,tsx会自动处理所有编译需求,非常适合写工具脚本。

额外提示

当前脚本的mkdir遇到已存在的文件夹会报错,可添加{ recursive: true }参数避免:

await mkdir(`./src/components/${componentName}`, { recursive: true })

内容的提问来源于stack exchange,提问作者rpm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 16:07:53