Dev 启动 18 秒的真相:原来是它在暗中使坏

今天被一个 18 秒的 astro dev 启动时间气到失语。按下回车的那一刻,我以为自己在启动一艘航天飞机,结果只是想打开一个本地页面。更扎心的是,astro build 明明很快,像是在我耳边轻声说一句:你慢,是你自己的事。

排查纪实

我先把目光投向 MDX,接着盯上 KaTeX,又顺手怀疑了一下 Shiki。每一个都像“有嫌疑”,最后一个个证明清白,搞得我开始怀疑人生:是不是我最近代码写得不够虔诚,才换来如此折磨。

真相时刻

真正的罪魁祸首很低调:Vite 在扫描大目录。项目里有 model/venv/,文件多到像一座小型图书馆,Windows 的文件监听被拖成了慢动作回放。

解决方案也很朴素:让 Vite 目不斜视,不要看这些大目录。加上下面这一段,速度瞬间回血,像换了新硬盘:

vite: {
  server: {
    watch: {
      ignored: ['**/model/**', '**/venv/**'],
    },
  },
},

收尾

当时我只想说一句:“太阴了,就是这个问题。“这句话配得上今天所有的戏剧性。下次 dev 启动慢,我会先检查有没有哪个大目录在暗中发力。Vite 很无辜,锅是我自己放进去的。

进一步改进:建立代码质量保障系统

解决了 dev 启动速度之后,我意识到需要一个更系统的代码质量保障机制。毕竟性能优化是好事,但如果代码质量不过关,优化再多也是在沙滩上建城堡。于是我决定建立一套完整的 lint + 类型检查 + Git hooks 工作流。

安装工具

首先安装必要的工具:

npm install -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-astro
npm install -D @astrojs/check typescript
npm install -D husky lint-staged

核心工具说明:

  • ESLint 9:代码规范检查(使用现代 flat config)
  • @typescript-eslint:TypeScript 语法检查
  • eslint-plugin-astro:Astro 组件检查
  • @astrojs/check:Astro 官方类型检查工具
  • husky 9:Git hooks 管理器
  • lint-staged:仅检查暂存文件(加速提交)

配置 ESLint

创建 eslint.config.js(ESLint 9 的 flat config 格式):

import eslintPluginAstro from 'eslint-plugin-astro';
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';

export default [
  // JavaScript/TypeScript 配置
  {
    files: ['**/*.{js,mjs,cjs,ts,tsx}'],
    languageOptions: {
      parser: tsparser,
      parserOptions: {
        ecmaVersion: 'latest',
        sourceType: 'module',
      },
    },
    plugins: {
      '@typescript-eslint': tseslint,
    },
    rules: {
      'no-unused-vars': 'off',
      '@typescript-eslint/no-unused-vars': ['warn', {
        argsIgnorePattern: '^_',
        varsIgnorePattern: '^_',
      }],
      '@typescript-eslint/no-explicit-any': 'warn',
      'no-console': 'off',
      'prefer-const': 'error',
      'no-var': 'error',
    },
  },

  // Astro 文件配置
  ...eslintPluginAstro.configs.recommended,

  // 忽略文件
  {
    ignores: [
      'dist/',
      'node_modules/',
      '.astro/',
      'venv/',
      'model/',
      'public/',  // 忽略第三方库
      '**/*.min.js',
      'tools/blog-clustering/**/*.py',
    ],
  },
];

更新 tsconfig.json

为了避免 TypeScript 扫描不必要的目录(比如之前导致 dev 启动慢的 venv/model/),我更新了排除列表:

{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": [
    "dist",
    "node_modules",
    "venv",      // 排除 Python 虚拟环境
    ".astro",    // 排除 Astro 缓存
    "model",     // 排除机器学习模型
    "public"     // 排除静态资源
  ],
  "compilerOptions": {
    "strictNullChecks": true
  }
}

添加 npm scripts

package.json 中添加代码质量检查命令:

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "type-check": "astro check",
    "validate": "npm run lint && npm run type-check && npm run build",
    "prepare": "husky"
  },
  "lint-staged": {
    "*.{js,mjs,cjs,ts,tsx,astro}": [
      "eslint --fix"
    ]
  }
}

命令说明:

  • npm run lint:检查代码规范
  • npm run lint:fix:自动修复可修复的问题
  • npm run type-check:TypeScript 类型检查
  • npm run validate:完整的质量检查(lint + 类型 + 构建)
  • prepare:安装依赖时自动初始化 husky

配置 Git Hooks

初始化 husky:

npx husky init

创建 pre-commit hook.husky/pre-commit):

npx lint-staged

这个 hook 会在提交前检查暂存的文件,只检查你修改的文件,速度很快。

创建 pre-push hook.husky/pre-push):

npm run lint

这个 hook 会在推送前运行完整的 lint 检查,确保推送到远程的代码符合规范。

踩坑记录

坑 1:第三方库被检查

第一次运行 npm run lint 时遇到了 339 个错误,其中 147 个来自 public/wordcloud2.js(第三方库使用了 var 而不是 let/const)。

解决方案:eslint.config.jsignores 中添加 public/ 目录。

坑 2:TypeScript 扫描 Python 虚拟环境

运行 npm run type-check 时出现错误:

Couldn't find package @astrojs/svelte (searching from e:/proj/blog/Misaka-Net-Blog/venv/Lib/site-packages/gradio/_frontend_code/...)

原因是 TypeScript 扫描了 venv/ 目录,其中包含 Gradio 的 Svelte 文件。

解决方案:tsconfig.jsonexclude 中添加 venv/model/public/ 等目录。

坑 3:Husky 9 命令变更

尝试使用 npx husky add .husky/pre-commit "npx lint-staged" 时失败:

husky - add command is DEPRECATED

原因是 Husky 9.x 改变了 API,不再支持 husky add 命令。

解决方案: 手动创建 hook 文件:

mkdir -p .husky
echo "npx lint-staged" > .husky/pre-commit
echo "npm run lint" > .husky/pre-push

最终工作流

日常开发:

  1. 修改代码
  2. git add 暂存文件
  3. git commit → 自动运行 lint-staged(只检查暂存文件,快速)
  4. git push → 自动运行 npm run lint(完整检查)

重要提交前:

运行 npm run validate 进行完整的三重检查(lint + 类型 + 构建)。

手动修复代码规范:

运行 npm run lint:fix 自动修复可修复的问题。

当前代码质量状态

  • ESLint:8 个警告(未使用的变量,可接受)
  • TypeScript:119 个错误(历史遗留问题,计划逐步修复)
  • 构建:✅ 正常(181 页)
  • Git Hooks:✅ 运行正常

小结

这套代码质量保障系统建立后,每次提交都会自动检查代码规范,推送前会再次全面检查,有效防止低质量代码进入代码库。虽然项目还存在一些历史遗留的类型错误,但现在至少有了一个自动化的防护网,可以逐步改进代码质量。

最重要的是,这套系统是 渐进式的

  • pre-commit 只检查暂存文件(快,不影响提交体验)
  • pre-push 进行完整检查(确保推送质量)
  • 不阻止已有问题(允许增量改进,不会因为历史问题阻塞开发)

下一步计划是逐步解决那 119 个 TypeScript 错误,让类型系统真正发挥作用。