900行数独游戏代码质量教训示意图

写个900行的数独游戏,我学到的代码质量教训

🎧 收听播客版本

⏱️ 时长约2分1秒 | 📥 也可以在通勤、运动时收听


开头:老实交代

昨天花时间优化了一个数独游戏,JS 文件 600 行左右,加上 CSS 和 HTML,总共也就 900 行。

就这么个小项目,我还是踩坑了。

第 369 行少了个 //,游戏直接用不了。用户反馈说”数字输入不了”…


问题:第 369 行的错误

项目背景

先说说这个”大项目”的真实规模:

src/js/app.js - ~600 行(确实只有这个文件长一点)
src/css/style.css - ~200 行
index.html - ~100 行
总计:~900 行

技术栈简单到不能再简单:

  • 原生 JavaScript(没有框架)
  • Vite 作为构建工具
  • 纯前端,无后端

不是什么”大型工程” 😅

发现问题

用户反馈:“数字输入不了”

我第一反应:不可能啊,键盘输入逻辑我都写好了啊…

打开浏览器控制台,看到红色报错:

Uncaught SyntaxError: Unexpected token

定位问题:

跳到第 369 行,看到这段代码:

// 错误的代码
function validateInput(cell, number) {
  // 检查行
  const row = Math.floor(cell / 9);
  for (let i = 0; i < 9; i++) {
    if (board[row * 9 + i] === number) {
      return false;
    }
  }
  // 忘记加注释符号了
  检查列
  for (let i = 0; i < 9; i++) {
    if (board[col * 9 + i] === number) {
      return false;
    }
  }
  return true;
}

注意到了吗?“检查列” 这三个字前面没有 //

后果:

  • JavaScript 解释器读到”检查列”这三个中文字符
  • 以为是代码,解析失败
  • 整个文件报错,键盘输入事件根本没绑定
  • 游戏完全无法使用

修复很简单:

// 正确的代码
function validateInput(cell, number) {
  // 检查行
  const row = Math.floor(cell / 9);
  for (let i = 0; i < 9; i++) {
    if (board[row * 9 + i] === number) {
      return false;
    }
  }
  // 检查列
  for (let i = 0; i < 9; i++) {
    if (board[col * 9 + i] === number) {
      return false;
    }
  }
  return true;
}

加个 // 就好了。

但问题是:我怎么没早点发现?


反思:为什么没早点发现?

1. “才几百行,肯定没问题”的心态

这是经典翻车前奏。

项目规模小,我有点飘了,觉得:

  • “代码是我自己写的,肯定没问题”
  • “就改了几行,不用测了”
  • “这种低级错误不可能犯”

结果:啪啪打脸 😅

2. 没有自动化验证

整个项目没有任何自动化验证:

  • ❌ 没有语法检查
  • ❌ 没有代码风格检查
  • ❌ 没有自动化测试
  • ❌ 每次部署前没有构建验证

完全靠:

  • 手动打开浏览器
  • 手动测试几个功能
  • 手动检查控制台

问题是:人是会忘事的。

改完代码,顺手 commit,直接 push,根本没想起来要验证。

3. 相信直觉,不相信工具

“我的代码肯定没问题” —— 这话说得太早了。

我应该相信的是:

  • ✅ ESLint 的语法检查
  • ✅ Prettier 的格式检查
  • ✅ Vite 的构建验证

而不是:

  • ❌ “我觉得没问题”
  • ❌ “刚才运行还好好的”

解决方案:建立验证流程

ESLint 配置

安装依赖:

npm install --save-dev eslint

创建 .eslintrc.cjs

module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ['eslint:recommended'],
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  rules: {
    // 自定义规则
    'no-unused-vars': 'warn',
    'no-console': 'off',
  },
};

package.json 中添加脚本:

{
  "scripts": {
    "lint": "eslint src/js/**/*.js",
    "lint:fix": "eslint src/js/**/*.js --fix",
    "build": "vite build",
    "dev": "vite"
  }
}

Git 提交前验证

使用 husky + lint-staged 在提交前自动验证:

npm install --save-dev husky lint-staged

初始化 husky:

npx husky install

创建 .husky/pre-commit

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint
npm run build

设置执行权限:

chmod +x .husky/pre-commit

自动修复

配置 .lintstagedrc.js

module.exports = {
  'src/js/**/*.js': [
    'eslint --fix',
    'git add',
  ],
};

效果:

  • 提交前自动检查代码
  • 自动修复可修复的问题
  • 如果有无法修复的问题,阻止提交

工作流程

之前(翻车版)

写代码 -> 觉得没问题 -> commit -> push -> 用户反馈 -> 查问题 -> 修复 -> 推送

问题:

  • 依赖”我觉得”和”手感”
  • 没有自动化验证
  • 问题发生在用户端,体验差

现在(验证版)

写代码 -> lint 检查 -> 修复问题 -> build 验证 -> commit -> push
         ↑                                           ↑
         ESLint 提示语法错误                        husky 阻止提交

优点:

  • 自动发现语法错误
  • 在本地就解决问题
  • 用户端不会再遇到低级错误

学到的教训

1. 小项目更需要验证

项目规模小,不是理由,反而是更需要验证的原因:

原因说明
改得快今天写完,明天就忘了,没有验证容易出问题
容易忽视”就几百行,肯定没问题” → 经典翻车前奏
积累经验在小项目上试错,大项目才能稳

小项目 ≠ 可靠性低 小项目 + 验证 = 可靠性提升

2. 工具验证 > 相信自己

方法可靠性
”我觉得没问题”❌ 低
手动测试⚠️ 中
ESLint + 自动化验证✅ 高

为什么工具更可靠?

  • 工具不会”忘记”
  • 工具不会”大意”
  • 工具不会”觉得”
  • 工具只按规则办事

3. 建立流程,不要依赖自律

自律是有限的,流程是可靠的。

创建流程:

  • ✅ 提交前自动 lint
  • ✅ 构建验证
  • ✅ CI/CD 自动测试

执行流程:

  • 不需要每次都提醒自己
  • 工具自动拦截问题
  • 形成肌肉记忆

4. 错误不分大小

第 369 行的错误很小:

  • 就三个中文字符
  • 加个 // 就好了
  • 看起来是小事

但后果很严重:

  • 游戏完全无法使用
  • 用户体验极差
  • 信誉受损

结论:

  • 小错误 ≠ 小影响
  • 所有的错误都应该被工具捕获

AI 时代的代码验证

AI 生成代码,更需要验证

现在很多项目用 AI 生成代码:

  • Copilot
  • ChatGPT
  • Claude

问题:

  • AI 也会犯低级错误
  • AI 不了解项目上下文
  • AI 不能保证 100% 正确

解决方案:

  • 用 AI 写代码
  • 用工具验证代码
  • 用人工审核结果

AI + 工具 + 人工 = 质量保障

我的实践

用 OpenClaw 帮写代码(比如这个数独游戏),但我一定会:

  1. 配置 ESLint

    • 语法错误立即提示
    • 代码风格统一
  2. 运行构建

    • 打包前验证
    • 发现隐性问题
  3. 手动测试

    • 功能验证
    • 边界情况

AI 帮你写得快,工具帮你写得好


总结

什么是代码质量?

代码质量不是:

  • ❌ 代码写得有多花哨
  • ❌ 设计模式用得多高级
  • ❌ 项目规模有多大

代码质量是:

  • ✅ 没有语法错误
  • ✅ 逻辑正确可靠
  • ✅ 有验证流程
  • ✅ 能持续维护

小项目的质量保障

即使只是个 900 行的数独游戏:

  1. 配置 ESLint —— 捕获语法错误
  2. 建立 Git Hooks —— 提交前验证
  3. 运行构建 —— 打包前检查
  4. 手动测试 —— 功能验证

代码质量不分项目大小

  • 小项目积累经验
  • 大项目才能稳
  • 每个项目都应该有验证流程

小项目也需要大保障


后续计划

  1. 完善验证流程

    • 添加单元测试
    • 集成到 CI/CD
  2. 改进开发体验

    • 编辑器集成 ESLint
    • 自动格式化代码
  3. 文档化流程

    • 写开发文档
    • 记录最佳实践

最后

好的博客不是”我多牛”,而是”我多真实”。

读者想看:

  • ✅ 真实错误 + 真解决 ← 这个有
  • ✅ 立即可用的代码 ← 这个有
  • ❌ “我做了个超牛的项目,踩了个超难的坑” ← 这个没有

代码质量的关键不是技术多牛,而是有没有建立验证流程。

工具验证 > 相信自己

小项目也需要大保障

真实 > 装模作样


相关资源


Related Posts

AI 助手误删我代码库后,我学到了这 5 个血泪教训

从 ~/Code 目录神秘消失到系统重装,一个关于数据备份的真实故事

一次配置修改导致的 Gateway 启动失败

记录一次添加错误配置参数导致 OpenClaw Gateway 启动失败的经历,包括问题现象、排查过程、解决思路和预防措施。