tsParticles CLI 构建命令深度解析:diststats 统计模块与 tsparticles-build 实战 📅 发布时间:2026/9/16 13:41:48 👁 浏览次数: tsParticles CLI 构建命令深度解析diststats 统计模块与 tsparticles-build 实战【免费下载链接】tsparticlestsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.项目地址: https://gitcode.com/GitHub_Trending/ts/tsparticles本文围绕 tsParticles 仓库中 build-diststats 模块文档 展开先介绍 tsParticles CLI 的安装与tsparticles-build构建命令用法再结合 diststats.ts 与 build.ts 源码深入讲解构建前后 dist 目录体积、文件数、目录数差异统计的完整实现机制帮助读者掌握如何在 tsParticles 单包构建中量化每次构建产物的变化。模块定位build-diststats 在 CLI 体系中的角色cli/commands/build-diststats/README.md 是 tsParticles CLI 家族的模块文档面向tsparticles/cli-command-build-diststats这个工作区包。从 package.json 可以看到{ name: tsparticles/cli-command-build-diststats, version: 4.3.3, type: module, description: tsParticles CLI, main: dist/diststats.js, scripts: { compile: pnpm run build:ts, build:ts:cjs: tsc -p src, build: pnpm run clear:dist pnpm run prettify:src pnpm run lint pnpm run compile pnpm run circular-deps pnpm run prettify:readme } }关键点该包通过tsc -p src使用 src/tsconfig.json 编译rootDir指向src、outDir指向../dist产物入口即main声明的dist/diststats.js它依赖工作区共享工具链tsparticles/eslint-config、tsparticles/prettier-config、tsparticles/tsconfig等均以workspace:*引用并启用 dependency-cruiser 做循环依赖检查它的消费方是构建命令包 cli/commands/build其中声明了tsparticles/cli-command-build-diststats: workspace:*依赖并在 build.ts 中导入import { getDistStats, type IDistStats } from tsparticles/cli-command-build-diststats;也就是说diststats 模块本身不是一个独立的可执行命令而是被tsparticles-build构建流程内部调用的统计组件——构建前采集一次快照构建后再采集一次最终把两者的差异打印出来。安装 CLIREADME 给出了三种包管理器的全局安装方式NPMnpm install -g tsparticles/cli-buildYarnyarn global add tsparticles/cli-buildPNPMpnpm global add tsparticles/cli-build安装后即可使用全局命令tsparticles-build也可以不全局安装直接通过npx tsparticles/cli-build按需运行。使用 tsparticles-build查看帮助npx tsparticles/cli-build --help或tsparticles-build --help执行构建npx tsparticles/cli-build或tsparticles-build命令主体由 cli/commands/build/src/build.ts 中的commanderCommand 定义。README 与 cli 总文档 cli/README.md 给出的常见用法tsparticles-build tsparticles-build --clean --lint --tsc tsparticles-build --bundle-webpack tsparticles-build --bundle-rollup完整选项清单来自源码定义以下选项逐项对应 build.ts 中的buildCommand.option(...)定义选项缩写作用说明--all-a执行全部构建步骤未指定任何 flag 时的默认行为等价于-b -c -d -l -p -t--bundle-rollup-b使用 Rollup 打包--bundle-webpack-使用 Webpack 打包不在--all默认步骤内需显式指定--clean-c清空 dist 文件夹--ci-CI 模式执行全部步骤只检查不修复格式且默认把--silent设为 true--circular-deps-r检查循环依赖--dist-d构建 dist 文件--lint-l对源码执行 Lint--prettify-p格式化源码--silent-s减少构建输出默认 false传入字符串false时显式关闭--ci下默认开启--tsc-t使用 TypeScript 构建库此外命令接受一个位置参数[path]表示项目根目录下的源码路径默认值为srcbuild.ts#L87。构建流程diststats 快照的采集时机buildCommand.action(...)build.ts#L89-L162的执行逻辑值得逐段拆解先计算all未指定任何构建 flag 时自动视为全量构建。这里有一个容易忽略的细节——doBundleWebpack: !!opts[bundleWebpack]直接取显式选项而其余步骤都是all || !!opts[...]即--all不触发 Webpack 打包只有--bundle-rollup走 Rollup构建前采集旧快照oldStats await getDistStats(basePath)basePath即process.cwd()按顺序执行各步骤任一环节失败立即抛出对应错误Dist clear failed、Source prettify failed、Lint failed、TypeScript build failed、Circular dependencies check failed、Webpack bundling failed、Rollup bundling failed、Project prettify failed、Dist files build failedclearDist → prettifySrc → lint → buildTS → checkCircularDeps → bundleWebpack → bundleRollup → prettifyReadme / prettifyPackageJson / prettifyPackageDistJson → buildDistFiles构建后再次采集快照并打印差异仅当!options.silent时执行if (!options.silent) { printDistStatsDiff(oldStats, await getDistStats(basePath)); }这就解释了为什么--ci模式默认静默——CI 场景下不需要在日志里追加体积变化报告。diststats 核心实现getFolderStats 与 getDistStats整个模块的源码只有 src/diststats.ts 一个文件约 70 行结构非常紧凑。数据结构 IDistStatsexport interface IDistStats { bundleSize: number; totalFiles: number; totalFolders: number; totalSize: number; }四个字段含义主打包文件bundle大小、总文件数、总目录数、总体积单位均为字节。getFolderStats递归遍历目录async function getFolderStats(folderPath: string, bundlePath?: string): PromiseIDistStats { const stats: IDistStats { bundleSize: 0, totalFiles: 0, totalFolders: 0, totalSize: 0, }; if (!existsSync(folderPath)) { return stats; // 目录不存在时返回全零统计 } const dir await opendir(folderPath), path await import(path); for await (const dirent of dir) { const increment 1; if (dirent.isDirectory()) { const subDirStats await getFolderStats(path.join(folderPath, dirent.name), bundlePath); stats.totalFolders subDirStats.totalFolders increment; stats.totalFiles subDirStats.totalFiles; stats.totalSize subDirStats.totalSize; } else { const fileStats await stat(path.join(folderPath, dirent.name)); stats.totalFiles; stats.totalSize fileStats.size; if (bundlePath path.join(folderPath, dirent.name) bundlePath) { stats.bundleSize fileStats.size; } } } return stats; }实现要点容错folderPath不存在时直接返回全零统计因此对“从未构建过、dist 尚不存在”的项目首次运行tsparticles-build也不会报错旧快照就是 0异步递归基于node:fs/promises的opendir迭代 对子目录递归getFolderStats把子目录的文件数、体积、目录数逐层累加每遇到一个子目录totalFolders额外1即increment计入当前层级bundle 命中判定只有当文件完整路径严格等于传入的bundlePath时才将其大小计入bundleSize。getDistStats定位主 bundle 文件export async function getDistStats(basePath: string): PromiseIDistStats { const path await import(path), distFolder path.join(basePath, dist), pkgInfo existsSync(path.join(distFolder, package.json)) ? (JSON.parse((await readFile(path.join(distFolder, package.json))).toString()) as { jsdelivr?: string; }) : {}, bundlePath existsSync(distFolder) pkgInfo.jsdelivr ? path.join(distFolder, pkgInfo.jsdelivr) : undefined; return await getFolderStats(distFolder, bundlePath); }这里的逻辑回答了“bundleSize 到底统计的是哪个文件”固定以basePath/dist为统计根目录若dist/package.json存在则读取其中的jsdelivr字段——这是 tsParticles 各单包package.json中约定指向 CDN 主文件的字段将dist与jsdelivr路径拼接得到bundlePath交给getFolderStats做精确匹配若 dist 不存在或没有jsdelivr字段则bundlePath为undefined此时bundleSize恒为 0但总文件数/目录数/体积统计仍然有效。差异报告printDistStatsDiff 的输出规则构建完成后的对比逻辑在 build.ts#L20-L48const minSize 0; function printDistStatsDiff(oldStats: IDistStats, newStats: IDistStats): void { const diffSize newStats.totalSize - oldStats.totalSize, bundleDiffSize newStats.bundleSize - oldStats.bundleSize, bundleSizeIncreased bundleDiffSize minSize, bundleSizeText bundleSizeIncreased ? increased : decreased, diffSizeText diffSize minSize ? increased : decreased, outputFunc bundleSizeIncreased ? console.warn : console.info, texts [ bundleDiffSize ? Bundle size ${bundleSizeText} from ${oldStats.bundleSize.toString()} to ${newStats.bundleSize.toString()} (${Math.abs(bundleDiffSize).toString()}B) : Bundle size unchanged, diffSize ? Size ${diffSizeText} from ${oldStats.totalSize.toString()} to ${newStats.totalSize.toString()} (${Math.abs(diffSize).toString()}B) : Size unchanged, Files count changed from ${oldStats.totalFiles.toString()} to ${newStats.totalFiles.toString()} (${(newStats.totalFiles - oldStats.totalFiles).toString()}), Folders count changed from ${oldStats.totalFolders.toString()} to ${newStats.totalFolders.toString()} (${(newStats.totalFolders - oldStats.totalFolders).toString()}), ]; for (const text of texts) { outputFunc(text); } }四条输出信息的语义Bundle size主 bundle 体积变化形如Bundle size increased from 100000 to 100005 (5B)无变化则输出Bundle size unchangedSizedist 总体积变化格式同上Files count文件数变化括号内为有符号差值Folders count目录数变化格式同上。一个值得注意的实现细节是outputFunc的选择当 bundle 体积增大时所有行都通过console.warn输出体积减小或不变时则走console.info。也就是说构建日志中如果出现警告色输出往往意味着本次构建让主 bundle 变大了——这是一个轻量但直接的“体积回归”提示。另外minSize 0的判定是严格大于体积不变时会被归类为 decreased 文案中的非增大分支配合外层bundleDiffSize/diffSize的 0 值短路实际打印的是 unchanged 文案不会产生误导。在仓库内如何触发该流程diststats 的差异报告在以下场景真实生效单包开发在cli/commands/*、cli/packages/*、cli/utils/*等包目录下运行pnpm nx run package:build见 cli/README.md 的 Workspace commands 一节或直接在包内pnpm run build最终都会走到tsc编译与 dist 产物生成由于 CLI 构建命令对这类包统一适用在具备完整 dist 产物的包中执行tsparticles-build即可看到上述四行统计输出模板工程脚本CLI 的create命令生成的空项目模板 cli/commands/create-utils/files/empty-project/package.json 中直接内置了{ scripts: { build: tsparticles-build, build:ci: tsparticles-build --ci, version: tsparticles-build -d git add package.dist.json } }这说明tsparticles-build是 tsParticles 生态内单包项目发布流程的标准入口--ci用于 CI 的只检查模式-d用于仅生成 dist 文件配合版本号更新。小结与适用前提diststats 模块tsparticles/cli-command-build-diststatsv4.3.3是构建命令的内部组件对外不暴露独立子命令其价值体现在每次tsparticles-build结束时自动输出 bundle/总体积/文件数/目录数四项差异统计口径固定为process.cwd()/dist主 bundle 的识别依赖 dist 内package.json的jsdelivr字段缺少该字段时 bundle 统计项恒为 0--silent含--ci的默认行为会完全跳过差异打印CI 流水线中如需观察体积变化应避免使用静默模式本文所有结论均基于当前仓库版本CLI 各包 4.3.3的源码命令选项以tsparticles-build --help实际输出为准。相关路径索引模块文档cli/commands/build-diststats/README.md统计实现cli/commands/build-diststats/src/diststats.ts模块包定义cli/commands/build-diststats/package.json构建命令与差异打印cli/commands/build/src/build.tsCLI 总览cli/README.md【免费下载链接】tsparticlestsParticles - Easily create highly customizable JavaScript particles effects, confetti explosions and fireworks animations and use them as animated backgrounds for your website. Ready to use components available for React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Solid, Riot and Web Components.项目地址: https://gitcode.com/GitHub_Trending/ts/tsparticles创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考