3、开发环境搭建:Node.js与npm/yarn/pnpm配置、TypeScript集成、ESLint与Prettier配置、Git Hooks设置

好,咱们正式开始搭建开发环境。这一步说白了,就是给你的项目打好地基。地基不稳,后面全是坑。我见过太多项目,代码写得挺漂亮,结果一拉下来跑不起来,或者格式乱七八糟,review 的时候吵得不可开交。嗯,咱们今天就把这些事一次性搞定。

3.1 Node.js 版本管理:别让版本坑了你

Node.js 版本这事,我吃过不少亏。有一次接手一个老项目,本地 Node 18,项目要求 Node 14,结果一跑就报错,排查了半天才发现是版本不兼容。从那以后,我养成了一个习惯:项目根目录必须锁定 Node 版本

我个人习惯用 nvm(Node Version Manager),它可以在不同项目间快速切换 Node 版本。你可以在项目根目录创建一个 .nvmrc 文件,写上你需要的版本号:

# .nvmrc
18.16.0

然后团队成员执行 nvm use 就能自动切到对应版本。如果你用的是 fnmvolta,原理类似。说白了,就是让团队所有人都用同一个 Node 版本,避免「我本地能跑啊」这种尴尬。

小技巧:package.json 里加上 "engines" 字段,配合 engine-strict 配置,可以强制约束 Node 版本。这样别人拉你的项目时,npm install 就会直接报错,而不是等到运行时才发现问题。

3.2 包管理器选型:npm、yarn 还是 pnpm?

这个问题,几乎每个前端团队都争论过。我个人的建议是:新项目直接用 pnpm。为什么?

  • npm:最基础,但 node_modules 结构扁平化,容易产生幽灵依赖。你明明没安装某个包,代码里却能引用它,这很危险。
  • yarn:比 npm 快,有 lock 文件,但本质上和 npm 是同一套逻辑。
  • pnpm:使用硬链接和符号链接,磁盘空间省了一大半。而且它严格隔离依赖,不会出现幽灵依赖。我在一个 monorepo 项目里用 pnpm,node_modules 从 2GB 降到了 400MB,安装速度也快了不少。

配置 pnpm 很简单,安装后执行 pnpm init 就行。如果你从 npm 迁移,记得删除 package-lock.json,然后执行 pnpm import 生成 pnpm-lock.yaml

# 全局安装 pnpm
npm install -g pnpm

# 初始化项目
pnpm init

# 安装依赖
pnpm add typescript -D
注意: 如果你用的是 pnpm,记得在 .npmrc 里加上 shamefully-hoist=true?不,千万别加。这个配置会把依赖扁平化,等于放弃了 pnpm 的核心优势。相信我,适应一下 pnpm 的依赖结构,你会爱上它的。

3.3 TypeScript 集成:从 JS 到 TS 的平滑过渡

TypeScript 现在基本是前端项目的标配了。但集成 TS 不是装个包就完事,配置项挺多的。我见过最惨的情况:项目里全是 any,TS 形同虚设。

先安装 TypeScript:

pnpm add typescript -D

然后生成 tsconfig.json

npx tsc --init

这是我的常用配置,你可以直接拿去用:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

这里有几个关键点:

  • strict: true:开启所有严格检查。别怕报错,早期报错比后期排查强百倍。
  • paths:配置路径别名,这样你可以用 @/components/Button 代替 ../../components/Button
  • esModuleInterop:解决 CommonJS 和 ES Module 的兼容问题。说白了,就是让你能正常 import 那些用 module.exports 导出的包。
避坑指南: 我曾经在一个项目里忘了配 skipLibCheck,结果每次编译都要检查 node_modules 里所有 .d.ts 文件,编译时间从 5 秒变成了 30 秒。加上 skipLibCheck: true 后,速度瞬间恢复。

3.4 ESLint 与 Prettier:代码质量的守门员

ESLint 管代码逻辑,Prettier 管代码格式。两者配合,基本能保证团队代码风格统一。我见过有人只用 ESLint,结果缩进、分号这些格式问题还得手动调,效率很低。

先安装:

pnpm add eslint prettier eslint-config-prettier eslint-plugin-prettier -D

ESLint 配置(.eslintrc.cjs):

module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier', // 放在最后,覆盖 ESLint 的格式规则
  ],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 'latest',
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint', 'prettier'],
  rules: {
    'prettier/prettier': 'error',
    '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
    'no-console': 'warn',
  },
};

Prettier 配置(.prettierrc):

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 100,
  "arrowParens": "always"
}
为什么要把 Prettier 集成到 ESLint 里? 因为这样你只需要运行 eslint --fix,就能同时修复代码质量和格式问题。省事,而且不会出现 ESLint 和 Prettier 规则冲突的情况。

3.5 Git Hooks:把检查自动化

配置好了 ESLint 和 Prettier,但如果没人执行,等于白配。Git Hooks 就是用来解决这个问题的——在提交代码前自动运行检查。

我推荐用 husky + lint-staged 这个组合。husky 负责管理 Git Hooks,lint-staged 只检查暂存区的文件,速度很快。

安装:

pnpm add husky lint-staged -D
npx husky init

然后在 .husky/pre-commit 文件里写上:

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

npx lint-staged

package.json 里配置 lint-staged:

{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,css,scss}": ["prettier --write"]
  }
}

这样,每次你执行 git commit 时,lint-staged 会自动检查并修复暂存区里的文件。如果检查不通过,commit 会被拒绝。嗯,这招很狠,但确实有效。

注意: 第一次配置 husky 时,记得执行 npx husky install 激活 hooks。另外,如果你用的是 CI/CD,记得在 CI 里也执行 npx husky install,否则 hooks 不会生效。

3.6 总结:一套完整的开发环境配置

好了,咱们把整个流程串起来。一个标准的项目初始化步骤应该是这样的:

  1. 用 nvm 切换到项目要求的 Node 版本
  2. 执行 pnpm init 初始化项目
  3. 安装 TypeScript 并配置 tsconfig.json
  4. 安装 ESLint + Prettier 并配置规则
  5. 安装 husky + lint-staged 并配置 pre-commit hook
  6. 提交代码,验证 hooks 是否生效

这套流程我用了好几年,从 Vue 2 到 React 18,从 Webpack 到 Vite,基本没变过。说白了,开发环境搭建这件事,一次配置,长期受益。别嫌麻烦,后面你会感谢现在认真搭环境的自己。

下一章,咱们聊聊项目结构设计。这个坑更多,我到时候给你讲讲我踩过的那些雷。