EN

快速开始

使用默认 TypeScript 模板创建、开发和打包 CLI 项目。

更新于
  1. 创建项目

    请先安装 Node.js 24.15 或更高版本

    命令会将 ship 作为项目名传给创建器。创建器会建立同名目录,并把 TypeScript 模板复制进去。它不会覆盖已有目录。如果你使用 Agent 自动创建,请参考 Agent 创建指引

    终端
    npm init func@latest ship
  2. 安装并检查生成的 CLI

    进入新目录、安装依赖,然后运行模板自带的帮助处理器。

    终端
    cd ship
    npm install
    npm run dev -- --help

认识生成的项目

在默认模板中,src 文件夹用于存放所有业务代码,tests 用于存放测试用例,如果你后续运行 build 命令则还会出现 dist 文件夹。通常在最后发布时,只有 dist 文件夹的内容会被发布。

项目结构
.
|-- src
|   |-- app.module.ts              根模块
|   |-- commands
|   |   |-- deploy
|   |   |   |-- deploy.command.ts  部署命令示例
|   |   |   |-- deploy.module.ts   部署功能模块
|   |   |   +-- deploy.service.ts  部署业务服务
|   |   +-- greet
|   |       |-- greet.command.ts   问候命令示例
|   |       |-- greet.module.ts    问候功能模块
|   |       +-- greet.service.ts   问候业务服务
|   |-- decorators
|   |   +-- url.decorator.ts       自定义 URL 值装饰器
|   |-- shared
|   |   |-- services
|   |   |   +-- output.service.ts  共享输出服务
|   |   +-- shared.module.ts       共享功能模块
|   +-- index.ts                   可执行入口
|-- tests
|   |-- cli
|   |   +-- smoke.test.ts          构建产物冒烟测试
|   |-- commands
|   |   |-- catch.test.ts          错误过滤测试
|   |   |-- deploy.test.ts         部署命令测试
|   |   |-- greet.test.ts          问候命令测试
|   |   +-- help.test.ts           帮助输出测试
|   +-- utils
|       +-- cli.ts                 CLI 测试工具
|-- .gitignore                     Git 忽略规则
|-- LICENSE                        开源许可证
|-- README.md                      项目说明
|-- package.json
|-- tsconfig.json
|-- vitest.cli.config.mts
+-- vitest.config.mts

安装依赖后,项目根目录还会出现当前包管理器对应的 lockfile;运行 build 后会生成 dist。这些生成文件没有列在上面的初始结构中。

根模块 (app.module.ts) 会收集并注册 func 可调用的命令和选项以及其他依赖。为了聚焦核心结构,下面省略了模板已经启用的可选能力配置:

src/app.module.ts
import { Module } from 'func'
import { DeployModule } from './commands/deploy/deploy.module'
import { GreetModule } from './commands/greet/greet.module'

@Module({
  imports: [GreetModule, DeployModule],
})
export class AppModule {}

开发时运行命令

模板通过普通 npm scripts 暴露 funcgo:

package.json
{
  "scripts": {
    "dev": "funcgo dev --",
    "build": "funcgo build"
  }
}

npm 标签中的 npm run dev -- <参数> 使用的是 npm 参数透传规范。第一个 -- 告诉 npm 停止解析自己的选项,把后续内容追加到 script;script 末尾 的 -- 用于区分 funcgo dev 和你的 CLI 参数。位于它后面的 token 不属于 funcgo。应用代码不需要自行解析或移除这两个分隔符。

终端
npm run dev -- greet
npm run dev -- greet --name Ada
npm run dev -- greet shout --name Ada

每次调用只执行一次 TypeScript 入口,无需生成生产 bundle,适合在编辑命令时快速验证。 其他包管理器的等价写法可以通过终端右上角切换。

添加第一个命令

创建一个带有固定命令路径和默认处理器的类。类名只在 TypeScript 代码中使用;用户实际输入的是 @Command 中的 path

src/commands/status.command.ts
import { Command, Handler } from 'func'

@Command({
  path: 'status',
  description: 'Print service status',
})
export class StatusCommand {
  @Handler()
  run() {
    console.log('All systems operational')
  }
}

将它加入命令列表,由 AppModule 注册后运行 npm run dev -- status

点击终端以聚焦

如果要添加别名或多个动作,请阅读命令 ;如果要接收标志和值,请阅读 字段选项

可选:把命令映射到全局

这一步不是使用 funcgo 的必要条件。只有希望在开发期间直接输入最终命令名进行调试(例如 ship)时才需要创建全局链接;否则继续使用 npm run dev -- <命令> 即可。

开发期间,包管理器可以把当前包映射到全局命令目录。由于 package.json#bin 指向 生成的 dist/bin.js ,请在项目根目录构建并创建链接:

终端
npm run build
npm link

# 使用 package.json#bin 中的键名

ship --help
点击终端以聚焦

这里的命令名是 ship,因此可以运行上面的 ship --help 。映射使用当前项目的构建产物;源码变化后请重新生成 bundle,必要时重新执行映射命令。

取消映射时,使用当前包管理器对应的解除映射命令:

终端
npm uninstall --global ship

监听文件并持续构建

funcgo build --watch 启动时会执行一次构建,之后默认监听 src/**/*.ts ,匹配文件变化后自动重新构建。可以在一个终端保持监听,在另一个终端调用已经全局链接的命令。按 Ctrl+C 停止监听。

终端
npm run build -- --watch

# 监听额外文件或自定义 glob
npm run build -- --watch --watch-path 'src/**/*.ts' --watch-path config.json

每个 --watch-path 都可以是文件、目录或正向 glob。配置文件位于 src 之外时,可以用它补充监听范围。生成目录、node_modules.git 会被忽略。

首次运行的常见问题

终端找不到全局命令

确认构建已经生成 dist/bin.js,在包根目录执行 npm link ,并使用 package.json#bin 中的键名,而不是包名调用命令。

Func 提示未知命令

请从已注册的命令列表导出命令类。仅创建文件和添加 @Command() 并不会自动注册该类。

npm 吞掉了本应传给 CLI 的选项

保留参数透传分隔符:使用 npm run dev -- status --json。只有 -- 后面的 token 才属于你的 CLI。

打包并准备发布

build script 会把配置的 TypeScript 入口打包到 func.outDir(模板默认 为 dist),并创建可执行的 bin.js。包内的 bin 字段决定用户安装后可以调用的命令名。

构建打包

funcgo build 默认使用 n24,生成面向 Node.js 24.15 及以上版本的产物。需要兼容较低版本时,可以通过 --target 选择 n22n20。Node.js 20 已停止维护,选择 n20 时每次构建都会显示 EOL 警告。

终端
npm run build
npm run build -- --target n22
npm run build -- --target n20

构建只检查 package.json#engines.node 是否与目标版本一致并给出警告,不会主动改写 package 信息。准备发布前,请确保 n20n22n24 分别对应最低版本 20.19.022.12.024.15.0

终端
npm run build
npm pack --dry-run

终端中的 dry-run pack 命令只展示即将发布的文件,不会真正发布。请确认列表中包含 bundle、 包信息、README 和 license;确认无误后,运行 npm publish 才会真正发布到 npm。自定义入口、输出、 外部依赖和监听范围见工具链