跳转至内容
There is a version suitable for your browser's language settings. Would you like to go to the english language of the site?
主页文档

命令

H1

Milkio 不仅仅用于构建支撑客户端的服务器,它也适用于编写可以在终端中直接使用的实用工具。

编写

位于 /apps/$/ 目录下的每个 API 都可以被视作一个命令。命令的使用方式与普通 API 相似,主要区别在于参数格式。尝试创建一个 /apps/$/say.ts 文件,来向世界问好..?

/* eslint-disable no-console */
import { defineApi, defineApiTest } from "milkio"
export const api = defineApi({
meta: {},
async action(
params: {
commands: Array<string>;
options: Record<string, string | boolean>;
},
context
) {
console.log(`hello world!`)
console.log(`Your Params:`, params)
},
})

你可能已经注意到,现在有两个参数可用:commandsoptions。Milkio 会自动从 argv 中解析这些参数。下面是一个命令执行的例子,以及它如何解析参数。

终端窗口
./app say hello world --foo=bar --enable
params: {
commands: ["hello", "world"],
options: {
foo: "bar",
enable: true,
},
}

使用

在打包之前,我们可以使用 bun command 命令来运行我们的命令。

终端窗口
bun command say hello world --foo=bar --enable

我们还可以将我们的应用打包成二进制文件。在 /package.jsonscripts 中,更改 build 命令,将打包我们的 HTTP 服务器改为打包我们的命令。

"build:command": "bun build ./run-command.ts --splitting --sourcemap=inline --outdir=./dist --target=bun --minify",

运行打包命令后,你的目录中将出现一个名为 app 的文件。

终端窗口
npm run build

尝试运行它,看看效果如何?

终端窗口
./app say hello world --foo=bar --enable

默认命令

当直接运行时,Milkio 会尝试执行名为 default 的命令。

例如,运行 ./app 或者 bun command 实际上会执行 /src/apps/$/default.ts 文件。

命令不存在

如果命令不存在,Milkio 将执行你在 /run-command.ts 文件中定义的 notFoundHandler 方法。该方法可以获取到被执行的命令名称和附带的参数。

/run-command.ts
async function command() {
const commandHandler = defineCommandHandler(await milkio, {
notFoundHandler(event) {
console.log("command not found", event)
}
})
await commandHandler(process.argv)
}

交互式 CLI

Bun 提供了一些内置方法,可用于创建交互式命令行界面。

console.log(prompt("What's your sign?"))
console.log(alert("Get ready to move on!"))
console.log(confirm("Do you really want to leave?"))

$ Shell

Bun 的 $ Shell 功能非常实用。

import { $ } from "bun";
await $`echo "Hello World!"`; // Hello World!

以文本形式获取 shell 的执行结果:

import { $ } from "bun";
const welcome = await $`echo "Hello World!"`.text();
console.log(welcome); // Hello World!\n

传递参数:

import { $ } from "bun";
const name = "World";
await $`echo "Hello ${name}!"`; // Hello World!

为了避免潜在的安全问题,Bun 的 $ Shell 会对模板字符串的插值进行参数化,这意味着,像下面这种方式不会正常工作:

import { $ } from "bun";
const path = "-a /";
await $`ls ${path}`; // 不会正常工作

你可以通过传递 raw 来绕过这个保护:

import { $ } from "bun";
const path = "-a /";
await $`ls ${{raw: path}}`; // 正常工作

更多用法,请参考 $ Shell 的文档。

使用命令启动 HTTP 服务器

我们可能需要开发一个同时包含命令和 HTTP 服务的应用,并通过一条命令来启动 HTTP 服务器。

由于 Milkio 的模块化设计,结合两者非常简单。你只需将 /run-serve.ts 中的代码复制到你的命令中即可。

import { defineApi, defineHttpHandler, envToNumber } from "milkio"
import { env } from "node:process"
import { milkio } from "../../../milkio"
export const api = defineApi({
meta: {},
async action(params: { commands: Array<string>; options: Record<string, string | boolean>; }, context) {
const httpHandler = defineHttpHandler(await milkio)
// 如果你使用 Bun
Bun.serve({
port: envToNumber(env.PORT, 9000),
fetch(request) {
return httpHandler({ request })
}
})
},
})