| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- import boxen from 'boxen';
- import dayjs from 'dayjs';
- import duration from 'dayjs/plugin/duration';
- import gradient from 'gradient-string';
- import { getPackageSize } from './utils';
- import type { Options as BoxenOptions } from 'boxen';
- dayjs.extend(duration);
- const boxenOptions: BoxenOptions = {
- padding: 0.5,
- borderColor: 'cyan',
- borderStyle: 'round',
- };
- // 起始时间戳经 process.env 传递。SSG 下 buildStart(vite 插件)与 buildEnd(react-router.config)
- // 可能被加载为 buildReport 的不同模块实例(react-router 用独立 loader 加载 config),模块级变量不可靠;
- // 而 process.env 在同一 Node 进程内必然共享,故用它跨钩子传起始时间。
- const START_ENV_KEY = '__BUILD_START_TS__';
- /** 打印「正在打包...」并把起始时间戳写入 process.env,供 printBuildComplete 读取。 */
- export function printBuildStart(): number {
- console.log('\n' + boxen(gradient(['cyan', 'magenta']).multiline('正在打包...'), boxenOptions));
- const now = Date.now();
- process.env[START_ENV_KEY] = String(now);
- return now;
- }
- /** 以 Promise 封装回调式的 getPackageSize,便于在 async 钩子(如 RR buildEnd)里 await。 */
- function measurePackageSize(folder: string): Promise<string | number> {
- return new Promise((resolve) => {
- getPackageSize({ folder, callback: resolve });
- });
- }
- /**
- * 打印「🎉 恭喜打包完成」总结框(用时 + 产物体积)。
- * @param folder 统计体积的产物目录(CSR → dist;SSG → dist/client)。
- * @param startTime 起始时间戳(毫秒);缺省则回退到 printBuildStart 记录的模块级值。
- *
- * SSG 模式必须在 React Router 的 buildEnd 钩子里调用:client/ssr 双环境构建、prerender、
- * 删除 server 目录都在 vite closeBundle 之后发生,只有 buildEnd 晚于全部步骤,
- * 在此打印才真正是「最后一行」。
- */
- export async function printBuildComplete(folder: string, startTime?: number): Promise<void> {
- const size = await measurePackageSize(folder);
- const envStart = process.env[START_ENV_KEY] ? Number(process.env[START_ENV_KEY]) : undefined;
- const start = startTime ?? envStart;
- const elapsed =
- start != null ? `总用时:${dayjs.duration(Date.now() - start).format('mm分ss秒')}\n` : '';
- console.log(
- '\n' +
- boxen(
- gradient(['cyan', 'magenta']).multiline(
- `🎉 恭喜打包完成\n${elapsed}打包后的大小为:${size}`
- ),
- boxenOptions
- )
- );
- }
|