On this page
@std/cli
Overview Jump to heading
Tools for creating interactive command line tools.
import { parseArgs } from "@std/cli/parse-args";
import { assertEquals } from "@std/assert";
// Same as running `deno run example.ts --foo --bar=baz ./quux.txt`
const args = parseArgs(["--foo", "--bar=baz", "./quux.txt"]);
assertEquals(args, { foo: true, bar: "baz", _: ["./quux.txt"] });
Add to your project Jump to heading
deno add jsr:@std/cli
See all symbols in @std/cli on
为什么使用 @std/cli? Jump to heading
此包帮助你构建具有极佳开发者体验的命令行工具。 它专注于核心功能:
- 解析标志和参数(
parseArgs),无需使用庞大的框架 - 提示输入敏感信息(
promptSecret) - 可靠测量显示宽度(
unicodeWidth),以实现整洁的终端输出 - 不稳定的增强功能以改善用户体验:加载动画、进度条、ANSI 光标控制 以及交互式选择菜单
当你想要一个轻量且可组合的命令行工具包时使用它。
对于包含子命令、丰富帮助和配置系统的更复杂命令行工具,
你仍然可以从 parseArgs 开始,并在此基础上构建自己的结构。
示例 Jump to heading
import { parseArgs } from "@std/cli/parse-args";
import { promptSecret } from "@std/cli/prompt-secret";
const args = parseArgs(Deno.args, {
alias: { v: "verbose" },
boolean: ["verbose"],
string: ["out"],
});
if (args.verbose) console.log("启用详细模式");
const token = await promptSecret("请输入 API 令牌:");
console.log(`写入到:${args.out ?? "标准输出"}`);
parseArgs轻量且无特定设计约束——非常适合简单工具; 对于复杂的命令行请考虑子命令和帮助文本模式。- 布尔值默认为 false,除非存在对应标志;如果需要,可以通过
booleanNegation选项支持--no-flag。 - 使用
stopEarly将--视为参数结束标志,并将剩余参数直接传递。
parseArgs:别名、默认值、收集、多选、否定、未知标志和 -- Jump to heading
import { parseArgs } from "@std/cli/parse-args";
const argv = [
"-v",
"--out=dist/file.txt",
"--tag",
"alpha",
"--tag",
"beta",
"--no-cache",
"--",
"--literally-a-file-flag",
];
const args = parseArgs(argv, {
alias: { v: "verbose" },
boolean: ["verbose", "cache"],
string: ["out"],
default: { out: "stdout" },
collect: ["tag"],
negatable: ["cache"],
unknown: (flag) => {
if (flag.startsWith("--") && flag !== "--") {
console.warn(`未知标志: ${flag}`);
return false; // 从解析结果中丢弃它
}
return true;
},
"--": true,
});
// args.tag -> ["alpha", "beta"]
// args.cache -> false (因为有 --no-cache)
// args.verbose -> true (因为有 -v)
// args.out -> "dist/file.txt"
// args["--"] -> ["--literally-a-file-flag"] (直接传递的参数)
promptSecret:掩码输入与清除提示行 Jump to heading
import { promptSecret } from "@std/cli/prompt-secret";
const token = await promptSecret("请输入令牌:", { mask: "*" });
// 可选:输入完成后清除提示行
await promptSecret("按回车继续", { mask: "", clear: true });
unicodeWidth:简单的列对齐 Jump to heading
import { unicodeWidth } from "@std/cli/unicode-width";
const rows = [
["名称", "宽度"],
["hello", String(unicodeWidth("hello"))],
["你好", String(unicodeWidth("你好"))],
["🐙octo", String(unicodeWidth("🐙octo"))],
];
const col1Width = Math.max(...rows.map((r) => unicodeWidth(r[0])));
for (const [a, b] of rows) {
const pad = " ".repeat(col1Width - unicodeWidth(a));
console.log(`${a}${pad} ${b}`);
}
不稳定的 UI 辅助:加载动画和进度条 Jump to heading
这些 API 标记为不稳定,可能会发生变化。
// 加载动画
import { Spinner } from "@std/cli/unstable-spinner";
const spinner = new Spinner({ message: "获取数据中..." });
spinner.start();
await new Promise((r) => setTimeout(r, 800));
spinner.stop();
// 进度条
import { ProgressBar } from "@std/cli/unstable-progress-bar";
const bar = new ProgressBar({ max: 5 });
for (let i = 0; i < 5; i++) {
await new Promise((r) => setTimeout(r, 300));
bar.value = i + 1;
}
bar.stop();