Skip to content

No-View 命令无界面,运行在 Node.js 的 Worker(worker_threads)中,适合执行任务、读写文件、系统集成等。你可以在命令入口文件中直接编写逻辑,按需调用提供的 API。

关键点

  • 建议将入口文件放在 src/no-view/<command>.ts
  • 通过独立的 vite.worker.config.ts 构建为 dist/<command>.mjs
  • package.json.commands[].name 必须与构建产物文件名一致

简单示例

ts
// src/no-view/storage-demo.ts
import {
  ctx,
  log,
  progress,
  done,
  onError,
  LocalStorage,
} from '@sofastapp/api/node';

onError();
(async () => {
  const { args } = ctx();
  log('start', { args });
  progress(0.2);
  const before = await LocalStorage.getItem<number>('demo.counter');
  const next = (before ?? 0) + 1;
  await LocalStorage.setItem('demo.counter', next);
  progress(1);
  done({ ok: true, counter: next });
})();

构建配置

ts
// vite.worker.config.ts
import { defineConfig } from 'vite';
import fs from 'node:fs';
import path from 'node:path';

function discoverNoViewInputs() {
  const inputs = {} as Record<string, string>;
  const dir = path.resolve(__dirname, 'src/no-view');
  try {
    for (const it of fs.readdirSync(dir, { withFileTypes: true })) {
      if (it.isFile() && it.name.endsWith('.ts'))
        inputs[it.name.replace(/\.ts$/, '')] = path.join(dir, it.name);
    }
  } catch {}
  return inputs;
}

export default defineConfig({
  build: {
    outDir: 'dist',
    emptyOutDir: false,
    rollupOptions: {
      external: ['worker_threads', /^node:.*/],
      input: discoverNoViewInputs(),
      output: {
        entryFileNames: '[name].mjs',
        chunkFileNames: 'assets/[name]-[hash].mjs',
        manualChunks: undefined,
      },
    },
  },
});

运行机制(简述)

  • 宿主会根据命令名在插件目录解析入口脚本,按以下顺序查找:
    • <pluginRoot>/<command>.mjs
    • <pluginRoot>/<command>.js
    • <pluginRoot>/workers/<command>.mjs
    • <pluginRoot>/workers/<command>.js 解析到入口后直接执行脚本。你只需要调用提供的 API(如 ctxlogprogressdonefailLocalStorage.*),不需要了解底层实现或协议细节。