#!/usr/bin/env ts-node import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { execSync, ExecSyncOptions } from 'child_process'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const pkgName = 'vitepress'; // 本地包名 const workspaceRoot = path.resolve(__dirname, '.'); const pkgPath = path.resolve(workspaceRoot, '../packages/src', pkgName); const nodePath = path.resolve(pkgPath, 'node_modules'); const distPath = path.resolve(pkgPath, 'dist'); const srcPath = path.resolve(pkgPath, 'src'); const tgzPath = path.resolve(workspaceRoot, '../packages/pkg', pkgName); const pkgOptions: ExecSyncOptions = { cwd: pkgPath, stdio: 'inherit', env: { ...process.env, NODE_PATH: pkgPath + '/node_modules:' + process.env.NODE_PATH } } const rootOptions: ExecSyncOptions = { stdio: 'inherit' } // 遍历目录文件的修改时间 function getAllTsFileMtimeMs(dirPath) { const results: number[] = []; function walk(currentPath) { const entries = fs.readdirSync(currentPath, { withFileTypes: true }); for (const entry of entries) { const fullPath = path.join(currentPath, entry.name); if (entry.isDirectory()) { walk(fullPath); // 递归处理子目录 } else if (entry.isFile() && entry.name.endsWith('.ts')) { const stat = fs.statSync(fullPath); results.push(stat.mtimeMs); } } } walk(dirPath); return results; } // 检查 node_modules 是否存在 function hasNodeModules(): boolean { return fs.existsSync(nodePath); } function installModules() { console.log(`[vitepress] 安装modules...`); execSync(`pnpm install`, pkgOptions); } // 检查 dist 是否存在 function hasBuilt(): boolean { return fs.existsSync(distPath); } // 检查 src 是否更新过 function isSourceNewerThanDist(): boolean { if (!fs.existsSync(distPath)) return true; const distMtime = fs.statSync(distPath).mtimeMs; const srcFiles = getAllTsFileMtimeMs(srcPath) console.log("distMtime: ", distMtime) console.log("srcFiles: ", srcFiles) return Math.max(...srcFiles) > distMtime; } function buildPackage() { console.log(`[vitepress] 正在构建本地包 "${pkgName}"...`); // workspace用法 // execSync(`pnpm --filter ${pkgName} build`, { stdio: 'inherit' }); // 不使用workspace // 进入子包目录,执行 build 脚本 // console.log(pkgOptions); execSync(`pnpm run build`, pkgOptions); execSync(`pnpm pack --pack-destination ${tgzPath} --json`, pkgOptions); try { execSync(`pnpm remove vitepress`, rootOptions); } catch (e) { console.log(e); } execSync(`pnpm add ../packages/pkg/vitepress/*.tgz`, rootOptions); } // 主流程 (function main() { if (!hasNodeModules()) { installModules(); } if (!hasBuilt() || isSourceNewerThanDist()) { buildPackage(); } else { console.log(`[vitepress] 构建已是最新,跳过构建`); } })();