代码洁癖患者会喜欢的几款 CLI 小工具

🎙️ 前言

在前端工程规范化高度成熟的今天,不管你有没有代码洁癖,你一定知道这些保证代码的 显性规范 的工具:

我们会纠结一个空行、一个空格、一个分号、未使用的变量、不规范的命名,会容忍不了 IDE 里任何一条黄色波浪线和背景色。

然而真正脏的工程问题,并不在代码写法上,而藏在项目依赖、版本冗余、垃圾文件、代码体量这些隐形角落。而这些问题,往往却是被大多数开发者无视或忽略的。

代码写得优雅,只是表层整洁;项目工程干净、依赖健康、版本可控、体量透明,才是高阶前端洁癖的终极追求。

很多项目看似能跑,实则暗藏大量技术隐债:

  • 陈旧依赖严重脱节:漏洞、老旧语法、废弃 API 默默堆积
  • 冗余依赖越积越多 :永远不会被用到的包常年盘踞在 node_modules,浪费流量和磁盘空间
  • 幽灵依赖定时炸弹:受包提升(package hoisting)影响引入间接依赖,让你的代码可以引用未安装的三方包,项目照跑无误,殊不知定时炸弹就这样埋下,尤其是你的项目还会发布 NPM 包,等于把问题扩散到你的用户,失掉信任
  • 项目代码体量模糊:无效代码、冗余文件、重复逻辑无人统计

以上任何一个问题,都非人力易解。本篇就来聊聊,作者(重度代码洁癖患者)极度依赖的几款极简、高效、专治项目脏乱差的 CLI 神器。

TL;DR

AI 开发工具盛行的时代,坚持古法制码已经不再现实。人们开始逐渐一有问题就向 AI 求救,比如「更新项目所有的依赖到最新」、「帮我查一下 Workspace 下所有的包的项目依赖是否有冗余或缺失」、「帮我计算一下代码量」,你可能第一时间会想到 AI,确实 AI 看起来很适合做这类苦力活,但...

「人之所思,鲜有全新」,你想到的问题,大抵早已有人求索过,并已有成熟解法可循。

是的,已经有很成熟的解决方案了,不仅免费,效率还远比 AI 工具高(在解决有明确方向问题的时候,传统的方案目前还是要远高效于 AI 的),何必浪费 Token 呢。说到底,AI 最终也是有可能就调用了传统工具来实现你想让它做的苦力活。

本文将介绍以下几款 CLI 工具:

工具 作用 说明
taze 更新依赖 用过就忘了旧爱 ncu
ncu 更新依赖 老牌工具,用了很多年
knip 检查依赖冗余或缺失(还有更多能力) depcheck 自闭前推荐了它,强大到配享官网
depcheck 检查依赖冗余或缺失 于 2023 年自闭
syncpack 依赖统一 这次写文章的惊喜发现,也是强大到配享官网
tokei 代码行统计 更快更智能
cloc 代码行统计 老牌工具,用了很多年

🥦 依赖保鲜 - taze / ncu

依赖版本是否保持鲜活,是判断一个前端和 Node 项目是否健康的重要依据。

每次接手一个旧的项目,我第一时间会看看项目依赖陈旧腐朽的程度,然后制定一个稳定升级的计划。我长期以来保持的一个习惯就是,每天打开工作区的第一件事情就是查看并更新项目依赖的版本。

这个习惯给我带来了不少好处,可以第一时间感知业界知名框架、库、工具链的更新,学习并了解新的 API;但也会第一时间受到二、三方包的问题影响。不稳定,你会说?毕竟升级是一把双刃剑,我们需要通过升级享受社区的红利(Bug 修复、功能增强、性能提升),但同时也要承受可能新引入的 Bug。

实际上,通过对二三包版本迭代的感知,我可以将出现问题的版本局限在更小的范围,并给二方包的同事或三方包的作者以更精准和及时的反馈,避免问题扩大,长期的稳定才是真的稳定。

维持惰性稳定,拒绝升级,导致依赖版本陈旧滞后带来的问题,除了无法享受社区带来的红利之外,更严重的,可能导致项目无法维护。我也见过不少这样的项目,开发依赖已经完全和现有的 Node 环境等脱节,甚至在安装阶段就报错。

你可以用以下两个工具:

  1. ncu 十多年的老牌工具了,目前还在积极维护,我用了很多年
  2. taze /ta:zei/ 波斯语的「新鲜」,antfu 开发,我现在已经抛弃旧爱 ncu 改投它的怀抱了

全局安装

非必需,但推荐。

全局安装,获得全局命令 tazencu

shell 复制代码
npm install -g taze
npm install -g npm-check-updates     # 注意不是 ncu

小试一下

小试一下做个简单的对比。

以下我们要对整个 Workspace(包括根目录)下的所有依赖进行检查并更新到 packages.json,使用的命令分别是 taze -r -w --forcencu -w -u

ncu 略慢,但差异并不明显,然而如果你用 pnpm -r exec 的话,相差就很明显了(taze 28s,ncu 约 4min):

后话:这也是我从 ncu 换成 taze 的最大原因,因为之前我都是用 pnpm -r exec ncu 来更新整个 Workspace,并不知道 ncu 还有个 -w 参数。这样体现了些文章的重要性,为了写的文章更严谨,我仔细翻看了 ncu 的参数,发现原来一直误会它了。

常用参数

tazencu 都提供了非常丰富的命令行参数,以下整理了一份常用的参数对比:

功能 taze ncu 备注
递归扫描 -r / --recursive w / --workspaces --deep taze -rncu --deep 对等,即使不属于 Workspace 的目录也会扫
写入模式 -w / --write ‑u / --upgrade 更新所有 package.json 下包的版本号到制定范围的最新版本
更新全局 ‑g / --global ‑g / --global ncu 明确说自己不会更新全局,但会给出更新命令;taze 可以用 taze -g --install 一键更新
忽略缓存 --force / -f --cacheClear taze 默认缓存,需要用 --force 绕过,强制拉取新数据;ncu 则需要通过 --cache 主动开启缓存;不一样的是 taze --force 不会清缓存,而只是绕过,而 ncu --cacheClear 会清掉缓存
交互模式 ‑I / --interactive ‑i / --interactive 交互模式,由你自己决定哪些升级包的最新版本写入 pacakge.json,即默认写入模式;注意 taze 是大写的 I
忽略包 --exclude pkg1,pkg2 ‑x / --reject pkg1,pkg2 排除不升级的包;taze 支持 pkg@versionRange 精细排除特定版本范围,比如 taze --exclude typescript@7 只屏蔽 v7,允许 v6 小版本升级
指定包 --include pkg1,pkg2 ‑f / --filter pkg1,pkg2 仅更新特定包,两者都支持正则
忽略路径 --ignore-paths <paths>
分组展示 --group --format group 更直观,也更美观;taze 默认,ncu 需加参数
超时设置 --request-timeout 120000 --timeout 120000 设置请求超时时间(ms),默认都是 30 秒
更新 Peer --peer --dep peer ncu 允许 --dep 参数更细节地控制更新哪类依赖,taze 只有 --peer 开关
执行安装 --install `--install <always never
并发控制 --concurrency N --concurrency N
日志控制 --loglevel <level> -l, --loglevel <level> 设置日志输出级别,控制终端输出信息量
输出 JSON --json --jsonUpgraded 以 JSON 格式输出升级内容(机器可读),命令执行后需要等待一定的时间

其他的一些不同:

  • 关于更新到目标版本范围,tazencu 的设计是完全不一样的,taze 使用了子命令模式
  • ncu 通过 --errorLevel N 可以控制退出码,而 taze 没有对等的能力,因此 ncu 更时长 CI 场景
  • ncu 提供了 -r, --registry 参数;taze 没有,但你可以用 .npmrc

配置 taze

第一步,安装开发依赖:

shell 复制代码
pnpm -w add -D taze

第二步 ,在 package.jsonscripts 添加命令:

json 复制代码
{
  ...
  "scripts": {
	  "taze": "taze -r"
  }
}

第三步 ,根目录下添加配置文件 taze.config.ts(或.tazerc.tazerc.jsontaze.config.{js,mjs,cjs}):

ts 复制代码
import {
  defineConfig
} from 'taze';
  
// https://github.com/antfu-collective/taze?tab=readme-ov-file#config-file
export default defineConfig({
  mode: 'major', // 更新版本范围
  write: true, // 写入 pacakge.json
  exclude: [ // 忽略哪些包,建议写好注释
    'typescript', // 暂不升 7,@typescript-eslint 不支持,会导致 Eslint 报错
    'eslint', // TODO up 10
    '@babel/*' // 暂不升 8,间接依赖的 @babel/runtime 导致构建失败
  ]
});

配置 ncu

第一步,安装开发依赖:

shell 复制代码
pnpm -w add -D npm-check-updates

第二步 ,在 package.jsonscripts 添加命令:

json 复制代码
{
  ...
  "scripts": {
	  "ncu": "ncu -w"
  }
}

第三步 ,根目录下添加配置文件 .ncurc.yaml(或 .ncurc.yml.ncurc.ncurc.json.ncurc.{js,mjs,cjs}

yaml 复制代码
# 写入 pacakge.json
upgrade: true
# 更新 dependencies 和 devDependencies(忽略 peerDependencies 等)
dep: dev,prod
# 分组展示(更美观)
format: group
# 超时设置
timeout: 120000
# 不要提示安装可以省时间
install: never
# 哪些包暂时不升级(可以加注释说明原因)
reject:
  - 'typescript', # 暂不升 7,@typescript-eslint 不支持,会导致 Eslint 报错
  - 'eslint' # TODO up 10
  - '@babel/*' # 暂不升 8,间接依赖的 @babel/runtime 导致构建失败

小结

tazencu 在更新依赖方面,都十分强大且好用,个人目前已经全面切换到了 taze,但全局命令依然两个都装。

每次升级完,仔细看输出,尤其注意大版本更新,若大版本不兼容,建议先把对应包配置到忽略列表。

🫟 依赖保洁 - knip / depcheck

项目依赖的另外一个很重要又容易被忽视的问题是依赖混乱的问题:

  • 版本号混乱,同名包在不同的 Workspace Package 下不一样,容易造成构建体积变大,甚至运行时问题
  • 依赖冗余,浪费流量
  • 依赖缺失,在有幽灵依赖的情况下较难及时发现,但却是一个隐藏的定时炸弹

版本号混乱的问题,可以用 tazencu 搞定,剩下的「多了和少了」的问题,可以用下面两个工具:

  1. knip 不仅能检查依赖,还可以查未被引用的文件、export 等(本文推荐的小工具中就它有官网,足见厉害)
  2. depcheck 检查依赖冗余和依赖缺失,于 2025/07 自闭并推荐了 knip

!\[Pasted image 20250810101926.png\|528]

全局安装

非必需,但推荐。

全局安装,获得全局命令 knipdepcheck

shell 复制代码
npm install -g knip
npm install -g depcheck

小试一下

利用两个工具做差不多的任务:检查整个 Workspace(包括根目录)。

可以看到 knip 完胜,简单且高效,还功能更多,而 depcheck 则需要借助 pnpm 的能力(并且需要借助参数 --no-bail 来保证不会提前退出)。

常用参数

depcheck 的功能相对简单,参数也比较少,以下整理了一份常用的参数对比:

功能 knip depcheck 备注
指定目录 直接传路径 knip ./packages/a depcheck ./packages/a 两者均支持直接传入项目目录路径作为第一个位置
递归扫描 自动识别 Workspaces ❌ 不支持,需借助 Shell 循环或 pnpm -r
输出 JSON --reporter json --json knip 支持多种输出;depcheck 只有简单 JSO
忽略包 配置 ignoreDependencies(CLI 无直接 flag,推荐配置文件) --ignores="pkg1,@scope/*"
忽略路径 配置 ignore --ignore-patterns=dist,covera
忽略 bin 包 配置 ignoreBinaries --ignore-bin-package knip 会自动忽略常用的 cross-envrimraf 等,而 depcheck 只能配置在 ignores(这个配置项貌似无效) 只能配置在
读取 .xxignore 无 CLI 参数,配置内设置 --ignore-path=.gitignore
跳过依赖 --include dependencies 只看无用依赖 --skip-missing=trueGitHub
仅检查某类问题 --include dependencies/files/exports
写入模式 --fix ❌ 不支持 knip 独有,从 package.json 移除未使用的依赖,不建议使用

配置 knip

knip 提供了在项目中初始化的命令 pnpm create @knip/config,但生的配置文件是 knip.json。由于配置相对简单,完全可以手动做。

第一步,安装开发依赖:

shell 复制代码
pnpm -w add -D knip

第二步 ,在 package.jsonscripts 添加命令:

json 复制代码
{
  ...
  "scripts": {
	  "knip": "knip"
  }
}

需要说明一下 --strict 参数,这是一个只在命令行的参数,配置文件中并没有它的位置。

有的时候带上 --strict 可以对齐 pnpm 的严格幽灵依赖检测,但 --strict 的隐含意思是仅扫描生产用的代码,什么意思呢,就是配置文件、单测、Storybook 等它不会管。

正因如此,并不建议你在 NPM scripts 中加上 --sctrict,而是你可以偶尔执行的时候带上这个参数检查看看有没有幽灵依赖。

第三步 ,根目录下添加配置文件 knip.config.ts(或 .knip.{json,jsonc}knip.{json,jsonc}knip.{ts,js}knip.config.{ts,js},也可以在 pacakge.json 添加 knip 字段):

ts 复制代码
import {
  KnipConfig
} from 'knip';

export default {
  workspaces: {
    '.': {
      entry: [ // 这是一个 Taro 小程序,因此会有多个 entry
        'src/app.tsx',
        'src/app.config.ts',
        'src/{pages,subpackages}/**/index.{ts,tsx,config.ts}'
      ],
      project: [
        'src/**/*.{ts,tsx,less,css}'
      ],
      paths: {
        '@/*': ['./src/*']
      }
    }
  },
  tags: ['-lintignore'],
  ignoreDependencies: [/^@tarojs\//]
} satisfies KnipConfig;

希望在 VSCode 或 WebStorm 下用 knip 的,官方也提供了插件,甚至还提供了给 AI 的 MCP Server 等,详见 Knip - Integrations

配置 depcheck

第一步,安装开发依赖:

shell 复制代码
pnpm -w add -D depcheck

第二步 ,在 package.jsonscripts 添加命令:

json 复制代码
{
  ...
  "scripts": {
	  "depcheck": "pnpm -r --include-workspace-root --no-bail exec depcheck"
  }
}

第三步 ,根目录下添加配置文件 .depcheck.yaml(或 .depcheck.yml.depcheck.json):

yaml 复制代码
ignorePatterns:
  - dist
  - __*
ignores:
  - '@/*'
  - '@babel/*'
  - '@commitlint/*'
  - '@kcuf/*config'
  - '@tarojs/*'
  - '@vitest/coverage-v8'
  - eslint-import-resolver-custom-alias
  - cross-env
  - lint-staged
  - rimraf
  - markdownlint-cli2
  - npm-package-json-lint
  - typescript
  - autoprefixer
  - depcheck
  - husky
  - lerna
  - less
  - postcss
  - react-refresh
  - stylelint

可以看到为了避免干扰,需要写好多忽略项。depcheck 默认只扫描 TS/JS 代码中的 import/require,无法识别像 package.json#scripts 和其他配置文件中的隐性依赖,因此会产生大量的误报。虽然它也提供了 --ignore-bin-package--specials 参数,但后者貌似不起作用,就是还需要写一大堆的 ignores

小结

无论是功能的强大性,还是配置的简单来说,knip 都略胜 depcheck 好几筹。

虽然我建议把更新 package.jsontazewrite: truencuupdate: true)的配置项开启,但提交改动到 Git 前请一定仔细看好了哪些包升级了,并着重关注大版本。若本地运行发现问题,及时回滚版本变更。

若发现小版本升级的包有问题,可以设置 overridepackage.json#resolutions(pnpm <11)暂时绕过。

🪢 版本混乱 - syncpack

写这篇文章的时候,从 knip 的文档 了解到 syncpack,一个能够梳理并解决依赖版本混乱的 CLI 工具,也是一个配享官网的工具。

syncpack 的功能和 knip 有一定的重叠,也可以检查和升级更新 syncpack update,但它更核心的能力是检查大型 Monorepo 项目下依赖项是否一致,这也正是它名字的由来。

全局安装

非必需,但推荐。

全局安装,获得全局命令 syncpack

shell 复制代码
npm install -g syncpack

小试一下

和上边介绍的几个小工具不一样,syncpack 主要以子命令的形式:

命令 功能 说明
list 列出所有依赖及出现次数
lint 列出版本不一致性问题
fix 修复 lint 查出的问题
format 修改 package.json 的格式 它会修改字段顺序,不会修改版本号,而字段顺序我一般交给 npmpackagejsonlint
update 更新依赖版本号 交给 taze

以下是 syncpack listsyncpack lint 的效果:

配置 syncpack

由于我刚认识 syncpack,而且它跟 taze 有一定的功能重叠,所以目前我暂时还没有将它写到 NPM scripts 下。但你依然可以试试装到项目依赖。

第一步,安装开发依赖:

shell 复制代码
pnpm -w add -D syncpack

第二步 ,在 package.jsonscripts 添加命令:

json 复制代码
{
  ...
  "scripts": {
	  "syncpack": "syncpack lint"
  }
}

第三步 ,根目录下添加配置文件 syncpack.config.ts(或 .syncpackrc.syncpackrc.config.{json,yaml,yml,js,ts,mjs,cjs}syncpack.config.{js,mjs,cjs},也可以在 pacakge.json 添加 syncpackconfig.syncpack 字段):

ts 复制代码
export default {
  indent: "    ",
} satisfies import("syncpack").RcFile;

小结

syncpack 可以帮你查你的项目下总共有多少依赖,每个依赖被分别声明了多少次,并且哪些依赖的声明可能不一致或有问题,从而使你的项目依赖更整洁。它同时具备更新依赖版本的能力(类似 taze)。

🧮 项目体量 - tokei / cloc

我比较喜欢数代码:

  • 新的代码方案替换原有的糟糕实现,想看一下新方案能够带来的代码量是否减少
  • 新写完一个功能,估算新增的代码量
  • 老板问项目体量
  • 想查一下项目中的巨型文件(可维护性杀手)

可用工具:

  • tokei Rust 写的代码行计算工具,自动忽略非项目代码,更快、更智能
  • cloc 老牌工具,用了很多年

我用了很久的 cloc,但 cloc 不够智能,首先它必须带路径参数,输入 cloc 不会给结果,而 cloc . 会把巨大的 node_modules 也算进去,耗时耗力还不是我们想要的结果。我需要一个更智能、更快的工具,就是 tokei,你只需要在项目目录下执行 tokei 即可得到答案,完全不用等,也不需要写复杂的参数。

tokei 之所以快,除了它是 Rust 写的之外,它还会主动忽略 node_modules.gitignore 等 Ignore 文件的内容,因此构建路基等也会被忽略。

我转投 tokei 另外一个重要的原因,也是第一大原因,是 cloc 会区分 JSJSX,却不区分 TSTSX,而 tokei 会。

安装

cloc 是 Perl 写的,而 tokei 是 Rust,两者都可以用 brew 安装:

shell 复制代码
brew install tokei
brew install cloc

小试一下

来查一个项目所有源码部分,包含工程配置、文档,但不包含 node_modules 和构建产物目录:

shell 复制代码
tokei
cloc . --exclude-dir=node_modules,dist

可以看出 tokei 无论在性能、易用性,还是美观上,都比老牌的 cloc 略胜一筹。两者数据稍有差异。另外就是,最好排除一下 pnpm-lock.yaml,这玩意儿可有万行呢。

常用参数

摊牌了,以下表格由 AI 整理(但也是经过了 Review 的)。

功能说明 tokei cloc 备注
目录 / 文件 tokei src cloc src tokei 默认当前目录,可以不写;但 cloc 必须写路径
排除 -e, --exclude <glob> --exclude-dir=dir1,dir2 --exclude-ext=js,min.js tokei 支持 glob;cloc 区分目录和后缀,不支持 glob
明细 -f, --files --by-file 输出每个文件的统计结果
指定语言 -t, --type TypeScript,TSX --include-lang=TypeScript tokei 语言名大小写敏感
排除指定语言 无原生参数 --exclude-lang=Markdown tokei 可搭配--exclude过滤后缀
输出格式 -o,--output json/yaml/cbor --json / --yaml / --xml / --csv / --sql cloc 输出格式更多,含 SQLXML
输出文件 重定向 > out.json --report-file=out.txt cloc 原生支持输出文件参数
排序输出 -s,--sort code/files/lines/comments/blanks --sort=code tokei 可按空白行、注释排序;cloc 仅支持 filescodecomment
读取 .gitignore 默认读取,可以 --no-ignore 关闭默认行为 不管 tokei 尊重 .gitignore 等,不会碰哪些不算在源码中的文件和目录,所以快;cloc 需要手动排除 node_modulesdist
统计隐藏 --hidden --include-hidden 默认两者都跳过隐藏文件
不递归 无,总是递归 --no-recurse tokei 无法关闭递归子目录,只能 -e 排除子目录
查看支持语言列表 -l, --languages --show-ext 打印全部识别语言和后缀映射
差异对比 不支持 diff --diff dirA dirB cloc 王牌能力,对比两套代码行数增减,支持 git commit
处理压缩包 不支持 原生支持 zip/tar.gz 等归档 cloc 可直接统计压缩包内部代码,tokei 需要先解压

小结

这两个工具都不需要在项目中安装和配置(因为不是 npm 包),虽然也有同名的 npm 包,切不要搞混了。虽然我是 cloc 的老用户, 但 tokei 更智能、更简单、更快,很难不让人「移情别恋」。

🏓 小技巧汇总

taze

shell 复制代码
taze -r           # 递归扫描,包括根目录和所有 Workspace 包
taze --force      # 绕过本地 npm meta 缓存(不是强制升级版本)
taze --maturity‑period‑exclude         # 忽略包发布冷却时间,直接看最新版

ncu

shell 复制代码
ncu --registry https://registry.npmmirror.com     # 指定 Resistry 提速
ncu -w                  # 扫描整个 Workspace,包括根目录和所有 Workspace Packages
ncu -u                  # 扫描当前目录,并更新
ncu -wu                 # 扫描整个 Workspace,并更新
ncu -ui                 # 交互式更新
ncu -u --prod           # 仅升级生产依赖 dependencies
ncu -u --dev            # 仅升级生产依赖 devDependencies
ncu -u vite,vitest      # 仅更新制定包

knip

shell 复制代码
knip --include unlisted         # 幽灵依赖
knip --include dependencies     # 未使用依赖
knip --include files            # 未使用文件
knip --include exports          # 未使用 exports

tokei

shell 复制代码
tokei -f -s lines    # 项目文件大小明细,以代码行数排序以便找到巨屎
tokei -t TypeScript,TSX -f -s lines        # 更精确一些,查找巨屎 TS 或 TSX 文件

cloc

shell 复制代码
cloc src packages-*/*/src    # 统计所有 src 下的代码
cloc src --by-file           # 项目文件大小明细,自动以代码行数排序

🙋 FAQ

❓ 明明刚发的包,taze 怎么没找到?

可能被缓存了,需要 taze --force

❓ 利用 pnpm -r 的 depcheck 如何忽略某 Workspace?

使用 pnpm --filter 反向过滤:

shell 复制代码
pnpm -r --no-bail --filter '!documentation' exec depcheck

❓ 如何升级到 升级到 alpha、beta、rc 等预发布版本?

taze newest

ncu 则提供了 --target 参数,取值 latest, newest, greatest, minor, patch, semver, @[tag],还有一个 --pre 参数专门用来升级预发布版本。

📌 链接

🪭 写在最后

不要把项目依赖成为黑盒,作为合格的开发者,0999

如果说 ESLint、Prettier 是代码级的洁癖 ,那 taze、ncu、knip、depcheck、tokei 这类 CLI 工具,就是 工程级的洁癖解药

它们不帮你格式化代码、不约束语法风格,却能帮你清理项目冗余、更新依赖版本、统计代码结构,让整个项目从「能跑」变成「干净、通透、健康、可维护」。

相关推荐
Csvn1 小时前
🛋️ requestIdleCallback:把非关键任务塞进浏览器的"空闲时间",告别卡顿
前端
江华森1 小时前
从 fork 到协程:一次完整的操作系统并发编程实操
前端·程序员
四千岁1 小时前
稀疏向量BM25Retriever不支持中文怎么办?jieba来帮忙
前端·javascript·后端
这是个栗子1 小时前
【JS代码分析】前端鉴权基础:Token 的本地存储与状态重置实践
开发语言·前端·javascript
颜进强1 小时前
14 - OpenSpec 老页面改造骨架:定位 + 增量 + 回归三件套
前端·后端·ai编程
做前端的娜娜子1 小时前
async/await 错误处理:try...catch vs .catch() 完全指南
前端·面试·掘金·金石计划
半个落月1 小时前
React 性能优化入门:用 memo 避免无关的子组件重复渲染
前端·react.js
北城笑笑2 小时前
Server 18 ,Nginx + Vite 前端部署排错实战:从 `/api/gpt/chat` 404 到 9012 后端服务的完整定位过程
linux·运维·前端·nginx·ubuntu·vue
江华森2 小时前
从抓包到嗅探:用 C 语言把《计算机网络》第 9-13 章全部跑一遍
前端