OmniTools 0.7.0 常用 CLI 命令与工具详解

OmniTools 0.7.0 命令面实测详解:npm 构建预览测试质检脚手架九脚本逐个回显(695 单测、6 e2e)、Node/git 工具链与托管层运维命令,含脚手架 ENOENT 与预览 404 排障实录

OmniToolsOmniToolsNodejs2026/10/28

OmniTools 0.7.0 常用 CLI 命令与工具详解

目标:把维护一套 OmniTools 0.7.0 站点会用到的命令面逐个讲清并实测——包括官方 package.json 定义的 9 个项目脚本(构建、预览、测试、质检、脚手架)、Node/npm/git 基础工具链,以及托管层(Nginx/systemd/curl)的日常运维命令。每条命令均带真实回显,含三条排障实录(脚手架 ENOENT、预览 404、lint 存量告警)。全部实测于 Ubuntu 24.04.5 + Node.js 20.20.2。

一、环境信息

  • 操作系统:Ubuntu 24.04.5 LTS x86_64;
  • 软件:OmniTools 0.7.0(tag v0.7.0,commit 5f8f4c7),源码 /opt/omni-tools,部署站点 /var/www/omnitools(8143 端口);
  • 工具链版本(实测):node v20.20.2、npm 10.8.2、git 2.43.0、nginx/1.24.0 (Ubuntu);
  • 安装与部署过程见 《Ubuntu 24.04 安装 OmniTools 0.7.0 指南》,本文所有命令可在该环境独立执行。

二、工具概览

先明确「命令面」的边界:OmniTools 应用本身没有 CLI、没有服务端 API——它构建后是纯静态单页应用,全部工具能力在浏览器内运行。因此本篇的「常用命令」是围绕这套应用的三层命令族:

命令族载体用途
项目脚本族(9 个)package.json 的 scripts,经 npm run 调用构建、预览、测试、质检、新工具脚手架
基础工具链node / npm / npx / git版本核对、源码版本管理
托管运维族nginx / systemctl / curl / ss站点托管、健康检查、版本核对

官方 9 个项目脚本全量清单(npm run 实测回显,输出节选(实测首尾)):

  build
    tsc && vite build
  serve
    vite preview
  test:e2e
    playwright test
  test:ui
    vitest --ui
  script:create:tool
    node scripts/create-tool.mjs
  lint
    eslint src --max-warnings=0 --fix
  typecheck
    tsc --project tsconfig.json --noEmit
  prepare
    husky install
  i18n:pull
    locize download --project-id ... --path ./public/locales
  i18n:sync
    locize sync --project-id ... --path ./public/locales ...

其中 test(vitest,交互式监视模式)与 prepare(husky 钩子安装,面向仓库贡献者)不在下文详解;i18n:pull/i18n:sync 面向官方 Locize 本地化平台维护者、需要项目凭据,自部署场景用不到,也不纳入详解。

三、前置条件

  • 已按安装篇完成源码获取与依赖安装(/opt/omni-tools 存在、npm install 已执行);
  • Node.js 20 与 git 就绪(版本核对命令见 4.1 节);
  • 本机已放行代理环境变量(涉及外网下载的命令需要,见安装篇 8.1/8.3 节排障);
  • 浏览器二进制仅 e2e 命令需要(4.6 节说明安装方式),其余命令无此依赖。

四、各工具详解

4.1 基础工具链核对:node / npm / git

维护动作前的第一组命令是核对工具链版本(实测回显):

node -v && npm -v && git --version
v20.20.2
10.8.2
git version 2.43.0
cd /opt/omni-tools && git rev-parse --short HEAD && git describe --tags --exact-match
5f8f4c7
v0.7.0

git rev-parse --short HEAD 的输出同时是构建注入产物、页面导航栏显示的 commit 标识,是核对「源码、产物、线上版本」三者一致性的基准值。

4.2 构建:npm run build

等价于 tsc && vite build:先做全量 TypeScript 类型检查(类型错误会让构建直接失败,等于内置门禁),再打包出带内容哈希的静态产物。

cd /opt/omni-tools && npm run build

实测回显(输出节选(实测首尾)):

> omni-tools@0.7.0 build
> tsc && vite build

vite v5.4.20 building for production...
dist/assets/index-DR-NHKWD.js                                       622.11 kB │ gzip:  72.50 kB
(中间为 228 个产物文件逐个输出)
dist/assets/ToolMultipleImageInput-B2lvA6na.js                      2,732.15 kB │ gzip: 672.75 kB
✓ built in 15.65s

构建结束以 ✓ built in Ns 收尾,产物在 dist/(实测 46MB、228 个文件)。Vite 会给出超 500KB 分块提示(最大的图片编辑分块 2.7MB),属官方已知状态,不影响使用。部署:

sudo cp -r /opt/omni-tools/dist/. /var/www/omnitools/ && sudo systemctl reload nginx

4.3 预览:npm run serve(vite preview)

用 Vite 内置的静态预览服务器在 4173 端口快速核对构建产物(部署前验证用):

cd /opt/omni-tools && npm run serve

实测启动回显:

> omni-tools@0.7.0 serve
> vite preview

  ➜  Local:   http://localhost:4173/
  ➜  Network: use --host to expose

另开终端验证:

curl -s -o /dev/null -w "HTTP %{http_code}, %{size_download} bytes\n" http://localhost:4173/
curl -s http://localhost:4173/ | grep -o "<title>[^<]*</title>"
HTTP 200, 834 bytes
<title>OmniTools</title>

⚠️ 排障实录(实测复现):若 dist/ 不存在(例如刚克隆的新源码树),npm run serve 能正常启动但访问全部 404——

HTTP 404, 0 bytes

根因:vite preview 只托管既有构建产物、不触发构建。解决:先 npm run build 再 serve,实测 404 恢复为 HTTP 200, 834 bytes。

4.4 单元测试:npm run test -- run 与 npx vitest run <文件>

package.json 的 test 脚本是交互式监视模式(改动即重跑,面向开发);命令行/CI 场景追加 run 参数执行一次性全量测试:

cd /opt/omni-tools && npm run test -- run

实测回显(输出节选(实测首尾)):

 Test Files  74 passed (74)
      Tests  695 passed (695)
   Start at  14:37:31
   Duration  13.64s (transform 1.89s, setup 6.11s, collect 21.29s, tests 2.06s, environment 14.82s, prepare 8.55s)

v0.7.0 共 74 个测试文件、695 个用例,全部通过、总耗时 13.64 秒。调试单个工具时只跑对应测试文件(速度毫秒级):

npx vitest run src/pages/tools/number/sum/sum.service.test.ts
RUN  v1.6.1 /opt/omni-tools

 ✓ src/pages/tools/number/sum/sum.service.test.ts  (12 tests) 3ms

 Test Files  1 passed (1)
      Tests  12 passed (12)
   Start at  14:37:17
   Duration  834ms (transform 40ms, setup 110ms, collect 23ms, tests 3ms, environment 127ms, prepare 80ms)

可视化面板模式(浏览器里逐用例查看、筛选重跑):

npx vitest --ui

实测启动回显(输出节选(实测首尾)):

 DEV  v1.6.1 /opt/omni-tools
      UI started at http://localhost:51204/__vitest__/

Error: spawn xdg-open ENOENT
    at ChildProcess._handle.onexit (node:internal/child_process:285:19) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'spawn xdg-open'
}
 ✓ src/pages/tools/number/random-port-generator/random-port-generator.service.test.ts  (24 tests) 10ms
(后续为逐文件监视模式测试输出,全部 ✓)

⚠️ 面板地址是 http://localhost:51204/__vitest__/(带 __vitest__ 路径);xdg-open 报错只说明服务器无图形会话、无法自动弹出浏览器,属预期现象,手动打开该地址即可,面板与测试服务均正常。

4.5 类型检查与代码质检:npm run typecheck / npm run lint

typecheck 与 build 中的 tsc 等价,可独立快速验证类型完整性(实测无输出即通过,退出码 0):

cd /opt/omni-tools && npm run typecheck; echo "exit: $?"
> omni-tools@0.7.0 typecheck
> tsc --project tsconfig.json --noEmit

exit: 0

lint 执行 ESLint 检查并自动修复(--fix,带 --max-warnings=0 的零容忍参数)。实测 v0.7.0 源码存在存量问题:

npm run lint; echo "exit: $?"

实测回显(输出节选(实测首尾)):

  6:3  error  '_options' is defined but never used  @typescript-eslint/no-unused-vars

✖ 211 problems (184 errors, 27 warnings)

exit: 1

⚠️ 注意事项:v0.7.0 的 lint 退出码为 1(211 个存量 error/warning,多为未使用变量类),这是仓库真实状态而非操作错误——不要把它当作 CI 部署门禁(build 内的 tsc 才是有效类型门禁);二开自检时关注自己改动文件的新增告警即可。--fix 只会自动修复可修项,本次实测未改动任何源码文件(git status --porcelain 为空)。

4.6 端到端测试:npm run test:e2e(playwright)

Playwright 会按 playwright.config.ts 自动完成「构建 → 起 4173 预览服务 → 跑用例」(webServer.command: 'npm run build && npm run serve' 配置实读),用例覆盖真实浏览器交互。首次使用需先安装浏览器二进制:

npx playwright install chromium

实测安装后缓存约 594MB(~/.cache/ms-playwright/chromium-1193)。跑单浏览器项目的全部用例(三个浏览器全跑用默认的 npm run test:e2e,chromium 之外还需 firefox/webkit 二进制):

npx playwright test --project=chromium --reporter=line

实测回显(输出节选(实测首尾)):

Running 6 tests using 3 workers

[1/6] [chromium] › src/pages/tools/image/png/compress-png/compress-png.e2e.spec.ts:37:7 › Compress PNG tool › should honor the maximum output size
[2/6] [chromium] › src/pages/tools/image/png/compress-png/compress-png.e2e.spec.ts:60:7 › Compress PNG tool with several files › should zip every compressed file
...
[6/6] [chromium] › src/pages/tools/string/join/string-join.e2e.spec.ts:8:7 › JoinText Component › should merge text pieces with specified join character

  6 passed (29.8s)

6 个用例(PNG 压缩、JPG 转 PNG、文本拼接三个工具的真实交互)全部通过,耗时 29.8 秒。二开新工具时可参照这 4 个 e2e 文件(src/pages/tools/**/*.e2e.spec.ts)的写法补充用例。

4.7 新工具脚手架:npm run script:create:tool

按官方约定在指定分类下生成新工具的四件套骨架(页面 index.tsx、元信息 meta.ts、逻辑 service.ts、类型 types.ts 与测试模板),并自动登记分类导出与语言包。以在 string 分类新建 text-repeater 为例:

cd /opt/omni-tools
mkdir -p src/pages/tools/string/text-repeater
npm run script:create:tool text-repeater string

实测回显:

Directory created: /opt/omni-tools/src/pages/tools/string/text-repeater
File created: /opt/omni-tools/src/pages/tools/string/text-repeater/index.tsx
File created: /opt/omni-tools/src/pages/tools/string/text-repeater/service.ts
File created: /opt/omni-tools/src/pages/tools/string/text-repeater/types.ts
File created: /opt/omni-tools/src/pages/tools/string/text-repeater/text-repeater.service.test.ts
File created: /opt/omni-tools/src/pages/tools/string/text-repeater/meta.ts
Added import in: /opt/omni-tools/src/pages/tools/string/index.ts

⚠️ 排障实录(实测复现,v0.7.0 缺陷):不先手工建目录直接执行会报错——

Error: ENOENT: no such file or directory, open '/opt/omni-tools/src/pages/tools/string/text-repeater/index.tsx'
    at async writeFile (node:internal/fs/promises:637:5)
    at async createToolFile (file:///opt/omni-tools/scripts/create-tool.mjs:70:3)

定位:scripts/create-tool.mjs 第 57 行以相对路径 . 为根逐段重建目标目录树,实际在仓库内误建了 ./opt/omni-tools/src/pages/tools/string/text-repeater 嵌套目录(find 实测 8 层),真正的工具目录没有被创建,写文件即 ENOENT。解决:如上先 mkdir -p 目标目录再执行;同时删掉误建的仓库内 ./opt 目录(rm -rf /opt/omni-tools/opt)。验证生成的骨架可直接通过类型检查与测试:

npm run typecheck && npx vitest run src/pages/tools/string/text-repeater/text-repeater.service.test.ts

实测回显(输出节选(实测首尾)):

> tsc --project tsconfig.json --noEmit

RUN  v1.6.1 /opt/omni-tools
 ✓ src/pages/tools/string/text-repeater/text-repeater.service.test.ts
 Test Files  1 passed (1)

演示完毕的还原(把源码树恢复干净):

rm -rf src/pages/tools/string/text-repeater
git checkout -- src/pages/tools/string/index.ts public/locales/en/string.json
git status --porcelain      # 无输出即还原完成(实测 0 行)

4.8 托管层运维命令:nginx / systemctl / curl

站点托管层的日常命令(均在 8143 站点实测):

sudo nginx -t                                   # 配置语法校验,任何 reload 前必做
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
systemctl is-active nginx                       # 服务状态
systemctl status nginx | head -3                # 状态详情(加载路径与运行时长)
sudo systemctl reload nginx                     # 改配置后平滑重载(不断连接)
sudo systemctl restart nginx                    # 彻底重启(排障用)
active
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-10-28 14:32:17 UTC; 32min ago

Loaded 行的 enabled 即开机自启已生效(4.8 节 systemctl enable --now 的结果)。重载动作会留档,journalctl 可查(实测回显):

journalctl -u nginx -n 3 --no-pager
Oct 28 14:59:21 omnitools-server systemd[1]: Reloading nginx.service - A high performance web server and a reverse proxy server...
Oct 28 14:59:21 omnitools-server nginx[4746]: 2026/10/28 14:59:21 [notice] 4746#4746: signal process started
Oct 28 14:59:21 omnitools-server systemd[1]: Reloaded nginx.service - A high performance web server and a reverse proxy server.
ss -ltn | grep 8143                             # 端口监听核对
curl -sI http://localhost:8143/ | head -3       # 健康检查
curl -s -o /dev/null -w "%{http_code} %{content_type}\n" http://localhost:8143/image/compress   # SPA 回退核对
curl -sI http://localhost:8143/assets/pdf.worker.min-DRfK9UlP.mjs | grep -i content-type        # MIME 核对
LISTEN 0      511          0.0.0.0:8143       0.0.0.0:*
LISTEN 0      511             [::]:8143          [::]:*
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
200 text/html
Content-Type: application/javascript

三条 curl 分别核对「入口可达、单页回退、模块脚本 MIME」,与配置篇 5.5/5.9 节的验证项一一对应,可作为上线后的例行巡检组合。

五、注意事项

  • 命令目录:4.2~4.7 节全部命令都要在 /opt/omni-tools 内执行(脚本依赖项目上下文),sudo 类托管命令除外;
  • 外网下载走代理:git clone、npm install、npx playwright install 在直连失败时统一加 export http_proxy=http://192.168.1.62:7897 https_proxy=http://192.168.1.62:7897(2026-10-28 实测该渠道可用;直连报错实录见安装篇 8.1 节);
  • lint 不是门禁:v0.7.0 有 211 个存量 lint 问题(4.5 节),持续集成请以 typecheck/build/test 为准;
  • script:create:tool 需先建目录:v0.7.0 脚手架缺陷,先 mkdir -p 再执行,并清理误建的 ./opt 目录(4.7 节排障实录);
  • 产物与源码的版本核对:git rev-parse --short HEAD(源码)与页面导航栏 v0.7.0 (5f8f4c7)(产物)应一致,不一致说明构建产物过期。

六、常见问题(FAQ)

Q1:npm run serve 启动正常但页面 404? dist/ 不存在(新克隆或清理过)。先 npm run build 再 serve,实测恢复 200(4.3 节排障实录)。

Q2:npm run script:create:tool 报 ENOENT? v0.7.0 脚手架以相对根重建目录树导致目标目录未创建。先 mkdir -p <目标目录> 再执行,并删除仓库内误建的 ./opt 目录(4.7 节排障实录)。

Q3:npx vitest --ui 报 spawn xdg-open ENOENT? 服务器无图形会话、无法自动开浏览器,属预期;面板实际已启动,手动访问 http://localhost:51204/__vitest__/ 即可(4.4 节实测回显)。

Q4:npm run lint 退出码 1 是不是把仓库搞坏了? 否,v0.7.0 源码自带 211 个存量 lint 问题(4.5 节回显);git status --porcelain 确认工作树未被动过即可。

Q5:git clone 报 GnuTLS recv error (-110)? 网络出口干扰,走代理重试(安装篇 8.1 节排障实录,实测代理下克隆成功)。

七、参考链接