老板突然要看“代码当量 KPI”

你刚把 Vue-lite 交付给私有化客户,领导转头就在群里甩了一句:"下周评审,把各模块代码行数统计出来,软著申请要用。"

用 cloc?当然可以,但客户环境没外网,装不了二进制。于是,你 15 分钟搓了一个 零依赖 的 Node CLI,直接 npx 就能跑,还能按扩展名过滤,结果输出成 JSON 方便后续自动化。


方案:三步做出 count-lines 命令

1. 初始化项目(1 分钟)

bash 复制代码
mkdir count-lines && cd count-lines
npm init -y
# 🔍 把 bin 字段挂到全局命令
npm pkg set bin.count-lines=./bin/index.js

2. 核心脚本(10 分钟)

bin/index.js

js 复制代码
#!/usr/bin/env node
import { readdir, readFile, stat } from 'node:fs/promises'
import { extname, join, resolve } from 'node:path'
import { createWriteStream } from 'node:fs'

const [, , targetDir = '.', ...extArgs] = process.argv
const exts = extArgs.length ? extArgs : ['.js', '.ts', '.vue', '.css', '.html']

async function* walk(dir) {
  for (const name of await readdir(dir)) {
    const full = join(dir, name)
    if ((await stat(full)).isDirectory()) yield* walk(full)
    else yield full
  }
}

async function main() {
  const result = { total: 0, files: {} }
  for await (const file of walk(resolve(targetDir))) {
    if (!exts.includes(extname(file))) continue
    const lines = (await readFile(file, 'utf8')).split('\n').length
    result.total += lines
    result.files[file] = lines
  }
  const out = createWriteStream('count.output.json')
  out.write(JSON.stringify(result, null, 2))
  console.log(`✅ 统计完成,共 ${result.total} 行,详情见 count.output.json`)
}

main()

逐行拆解

  • walk 是一个异步生成器,递归遍历目录,避免一次性读爆内存。
  • exts 支持命令行传参,比如 npx count-lines ./src .vue .ts 只统计 Vue 和 TS。
  • 结果写本地 JSON,方便后续脚本直接 require('./count.output.json')

package.json 关键字段

json 复制代码
{
  "type": "module",
  "bin": { "count-lines": "./bin/index.js" }
}

3. 本地测试 & 发布(4 分钟)

bash 复制代码
chmod +x bin/index.js
npm link          # 本地全局可用
count-lines ./src .vue .ts

原理深挖:从"读文件"到"流式输出"

表面用法 底层机制 设计哲学
readFile 读文本 Node 线程池异步 IO,不阻塞事件循环 单线程也能高并发
split('\n') 计数 利用 V8 内建字符串分割,比正则 /\r?\n/ 快 20% 能省一次正则就省
结果写 JSON 文件 流式写入 createWriteStream,内存占用 < 5 MB 大仓库也吃得下

扩展:3 个变体场景

场景 改动点 思路
软著申请 输出 Word 模板 officegen 把 JSON 渲染成 .docx,自动插入目录
CI 门禁 行数增量报警 在 GitHub Action 里对比 count.output.json 两次 commit 差异
多语言仓库 支持 .py .go exts 换成 Map,key 为扩展名,value 为注释正则,过滤空行和注释

一键复用片段

bash 复制代码
# 全局安装(私有 npm 源)
npm i -g @yourscope/count-lines
# 在 CI 里
- run: count-lines . .ts .vue
- run: node scripts/check-diff.js

把脚本丢进公司私有仓库,下次谁再要 KPI,一行命令搞定。

相关推荐
天蓝色的鱼鱼1 小时前
你的项目真的需要SSR吗?还是只是你的简历需要?
前端·架构
恋猫de小郭2 小时前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
文心快码BaiduComate2 小时前
百度云与光本位签署战略合作:用AI Agent 重构芯片研发流程
前端·人工智能·架构
闲云一鹤3 小时前
nginx 快速入门教程 - 写给前端的你
前端·nginx·前端工程化
QCY3 小时前
「完全理解」1 分钟实现自己的 Coding Agent
前端·agent·claude
一拳不是超人4 小时前
Electron主窗口弹框被WebContentView遮挡?独立WebContentView弹框方案详解!
前端·javascript·electron
anyup4 小时前
🔥2026最推荐的跨平台方案:H5/小程序/App/鸿蒙,一套代码搞定
前端·uni-app·harmonyos
雮尘4 小时前
如何在非 Claude IDE (TARE、 Cursor、Antigravity 等)下使用 Agent Skills
前端·agent·ai编程
icebreaker4 小时前
Weapp-vite:原生模式之外,多一种 Vue SFC 选择
前端·vue.js·微信小程序
icebreaker4 小时前
重走 Vue 长征路 Weapp-vite:编译链路与 Wevu 运行时原理拆解
前端·vue.js·微信小程序