项目新建

69 阅读8分钟

npm / pnpm

通过下载 nvm 来管理 node 版本

框架获取

通过 vite 获取 vue3/React 项目

使用 NPM:

npm create vite@latest

使用 Yarn:

yarn create vite

使用 PNPM:

pnpm create vite

然后按照提示操作即可!

代码规范工具下载与配置

下载 eslint

pnpm create @eslint/config@latest

#禁用ESLint中与Prettier冲突的格式化规则
pnpm install eslint-config-prettier eslint-plugin-prettier --save-dev

对于 TS 会自动下载下面的包 eslint, @eslint/js, globals, typescript-eslint, eslint-plugin-vue, jiti

配置

eslint.config.cjs

const eslintPluginVue = require("eslint-plugin-vue");
const eslintPluginPrettier = require("eslint-plugin-prettier");
const eslintPluginPrettierRecommended = require("eslint-plugin-prettier")
  .configs.recommended;
const vueParser = require("vue-eslint-parser");
const tseslint = require("@typescript-eslint/parser");
const globals = require("globals");
// const autoImportGlobals = require("./.eslintrc-auto-import.json");

module.exports = [
  {
    ignores: [
      "dist",
      ".gitignore",
      "package.json",
      "package-lock.json",
      "dist-ssr",
      "*.local",
      ".npmrc",
      ".DS_Store",
      "dev-dist",
      "dist_electron",
      "*.d.ts",
      ".prettierrc.js",
      ".stylelintrc.js",
      "commitlint.config.cjs",
      "vite.config.js",
      "src/assets/**",
      "eslintrc-auto-import.json",
      "eslint.config.cjs",
    ],
  },
  {
    files: ["**/*.vue", "**/*.js"],
    languageOptions: {
      parser: vueParser,
      globals: {
        ...globals.browser,
        ...globals.node,
        // ...autoImportGlobals.globals,
        Vue: "readonly",
        defineProps: "readonly",
        defineEmits: "readonly",
        defineExpose: "readonly",
        withDefaults: "readonly",
        ref: "readonly",
        reactive: "readonly",
        computed: "readonly",
        watch: "readonly",
        onMounted: "readonly",
        onUnmounted: "readonly",
        window: "readonly",
        document: "readonly",
        console: "readonly",
        localStorage: "readonly",
        sessionStorage: "readonly",
      },
      parserOptions: {
        parser: tseslint,
        ecmaVersion: "latest",
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
    plugins: {
      vue: eslintPluginVue,
      prettier: eslintPluginPrettier,
    },
    rules: {
      ...eslintPluginVue.configs["vue3-recommended"]?.rules, // 从 eslintPluginVue.configs['vue3-recommended'] 中扩展规则
      ...eslintPluginPrettierRecommended.rules, // 从 eslintPluginPrettierRecommended 中扩展规则
      "vue/component-definition-name-casing": "off", // 关闭 Vue 组件定义名称大小写检查
      "vue/singleline-html-element-content-newline": ["off"], // 关闭单行 HTML 元素内容换行检查
      "comma-dangle": "off", // 关闭尾随逗号检查
      "no-undef": "error", // 未定义变量报错
      quotes: ["error", "single", { allowTemplateLiterals: true }], // 强制使用单引号,允许模板字符串
      "no-undefined": "off", // 关闭未定义检查
      "no-unused-vars": "error", // 未使用变量报错
      "no-irregular-whitespace": "error", // 禁止不规则的空白字符
      "space-before-function-paren": 0, // 函数括号前不允许有空格
      "arrow-spacing": [2, { before: true, after: true }], // 箭头函数前后必须有空格
      "block-spacing": [2, "always"], // 块内必须有空格
      "brace-style": [2, "1tbs", { allowSingleLine: true }], // 大括号风格,允许单行
      "object-property-newline": "off", // 关闭对象属性换行检查
      "jsx-quotes": [2, "prefer-single"], // JSX 属性值强制使用单引号
      "key-spacing": [2, { beforeColon: false, afterColon: true }], // 关键字前后必须有空格
      "keyword-spacing": [2, { before: true, after: true }], // 关键字前后必须有空格
      "new-cap": [2, { newIsCap: true, capIsNew: false }], // 构造函数必须使用 new 调用
      "new-parens": 2, // new 表达式后必须有小括号
      "no-array-constructor": 2, // 禁止使用 Array 构造函数
      "no-caller": 2, // 禁止使用 caller 和 callee
      "no-class-assign": 2, // 禁止修改类
      "no-cond-assign": 2, // 禁止条件赋值
      "no-const-assign": 2, // 禁止重新赋值 const 变量
      "no-control-regex": 0, // 禁止控制字符
      "no-delete-var": 2, // 禁止删除变量
      "no-dupe-args": 2, // 禁止重复参数名
      "no-dupe-class-members": 2, // 禁止重复类成员
      "no-dupe-keys": 2, // 禁止重复键名
      "no-duplicate-case": 2, // 禁止重复 case 标签
      "no-empty-character-class": 2, // 禁止空字符类
      "no-empty-pattern": 2, // 禁止空模式
      "no-eval": 2, // 禁止使用 eval
      "no-empty": 2, // 禁止空代码块
      "no-extra-boolean-cast": 2, // 禁止多余的布尔值转换
      "no-extra-parens": [2, "functions"], // 禁止多余的括号
      "no-fallthrough": 2, // 禁止 fallthrough
      "no-floating-decimal": 2, // 禁止浮点小数
      "no-func-assign": 2, // 禁止重新赋值函数
      "no-unexpected-multiline": 2, // 禁止意外的多行
      "no-useless-escape": 0, // 禁止不必要的转义
      "array-bracket-spacing": [2, "never"], // 数组括号内不允许有空格
    },
  },
];

下载 prettier

# Prettier 核心包
pnpm add prettier -D
# StyleLint 与 Prettier 集成的关键插件(下面安装,这里不安装)
pnpm add stylelint-prettier stylelint-config-prettier -D
  • stylelint-prettier:将 Prettier 作为 StyleLint 的规则运行,让 Prettier 的格式化结果成为 StyleLint 的检查标准。
  • stylelint-config-prettier:关闭所有与 Prettier 冲突的 StyleLint 规则(避免两者格式化逻辑冲突)。

配置

新建文件 prettier.config.cjs

文件名中的 .cjs 后缀明确告诉 Node.js:「这是一个 CommonJS 模块」,不受项目 package.json 中 type: "module" 的影响。

配置内容例子

module.exports = {
  printWidth: 120, // 一行的字符数换行
  tabWidth: 2, // 一个tab代表几个空格数
  useTabs: false, // 是否使用tab进行缩进
  singleQuote: true, // 字符串是否使用单引号
  semi: false, // 行尾是否使用分号,默认为true
  trailingComma: "none", // 是否使用尾逗号
  arrowParens: "avoid", // 箭头函数单变量省略括号
  bracketSpacing: true, // 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
  endOfLine: "auto", // 保留在 Windows 和 Unix 下的换行符
  quoteProps: "preserve", // 对象属性的引号使用
};

下载 stylelint

#整合
pnpm i stylelint stylelint-config-standard stylelint-config-prettier stylelint-order stylelint-prettier -D

# 安装posthtml
pnpm add postcss-html -D

# 安装postcss-scss
pnpm add postcss-scss -D

# (可选)如果使用 SCSS/Sass
pnpm add stylelint-config-standard-scss -D


# 核心依赖:StyleLint 本体 + 标准规则集(解释,不用安装)
pnpm add stylelint stylelint-config-standard -D

# 安装 stylelint-order 插件(解释,不用安装)
pnpm add stylelint-order -D

  • stylelint-order 是一个 StyleLint 插件,用于强制 CSS/SCSS 等样式文件中的属性排序,让代码风格更一致,提高可读性和可维护性。例如,强制所有样式中的 display 放在 color 之前,margin 放在 padding 之前等。

配置

新建文件 .stylelintrc.json

配置内容例子如下

{
  "extends": ["stylelint-config-standard", "stylelint-prettier/recommended"],
  "ignoreFiles": [
    "**/*.json",
    "**/*.md",
    "**/*.yaml",
    "node_modules/",
    "dist/",
    "public/",
    "docs/",
    "**/*.js",
    "**/*.ts",
    "**/*.cjs",
    "**/*.min.css"
  ],
  "plugins": ["stylelint-order"],
  "customSyntax": "postcss-html",
  "overrides": [
    {
      "files": ["**/*.(vue|html)"],
      "customSyntax": "postcss-html"
    },
    {
      "files": ["*.scss", "**/*.scss"],
      "customSyntax": "postcss-scss"
    }
  ],
  "rules": {
    "selector-pseudo-class-no-unknown": [
      true,
      {
        "ignorePseudoClasses": ["deep"]
      }
    ],
    "block-no-empty": true,
    "function-url-quotes": "never",
    "color-hex-length": "long",
    "selector-type-no-unknown": [
      true,
      {
        "ignoreTypes": ["custom-tag"]
      }
    ],
    "selector-pseudo-element-no-unknown": [
      true,
      {
        "ignorePseudoElements": ["v-deep"]
      }
    ],
    "no-descending-specificity": null,
    "at-rule-no-unknown": [
      true,
      {
        "ignoreAtRules": ["extend", "include", "mixin"]
      }
    ],
    "comment-no-empty": true,
    "shorthand-property-no-redundant-values": true,
    "value-no-vendor-prefix": true,
    "property-no-vendor-prefix": true,
    "order/properties-order": [
      "position",
      "top",
      "right",
      "bottom",
      "left",
      "z-index",
      "display",
      "justify-content",
      "align-items",
      "float",
      "clear",
      "overflow",
      "overflow-x",
      "overflow-y",

      "margin",
      "margin-top",
      "margin-right",
      "margin-bottom",
      "margin-left",
      "border",
      "border-style",
      "border-width",
      "border-color",
      "border-top",
      "border-top-style",
      "border-top-width",
      "border-top-color",
      "border-right",
      "border-right-style",
      "border-right-width",
      "border-right-color",
      "border-bottom",
      "border-bottom-style",
      "border-bottom-width",
      "border-bottom-color",
      "border-left",
      "border-left-style",
      "border-left-width",
      "border-left-color",
      "border-radius",

      "padding",
      "padding-top",
      "padding-right",
      "padding-bottom",
      "padding-left",

      "width",
      "min-width",
      "max-width",
      "height",
      "min-height",
      "max-height",

      "font-size",
      "font-family",
      "font-weight",
      "text-align",
      "text-justify",
      "text-indent",
      "text-overflow",
      "text-decoration",
      "white-space",
      "color",

      "background",
      "background-position",
      "background-repeat",
      "background-size",
      "background-color",
      "background-clip",

      "opacity",
      "filter",
      "list-style",
      "outline",
      "visibility",
      "box-shadow",
      "text-shadow",
      "resize",
      "transition"
    ]
  }
}


在.vscode/settings.json 中添加以下配置:

{
  "editor.tabSize": 2,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },

  "eslint.validate": ["javascript", "typescript", "javascriptreact", "vue"],
  // 修改位置:设置 => settings.json 配置文件中新增
  "fileheader.configObj": {
    "autoAdd": true // 自动添加头部注释开启才能自动添加
  },
  "stylelint.enable": true,
  // 自动修复的文件类型
  "stylelint.validate": [
    "css",
    "scss",
    "vue",
    "less",
    "html",
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  "editor.dropIntoEditor.preferences": []
}

插件使用问题

项目使用中 stylelint 出现Unknown word 报错,配置文件(.stylelintrc.json 和.vscode/settings.json)都正确。检查后发现 stylelint 不受.stylelintrc.json 配置文件的影响,可能是 vscode 本地的 settings.json 文件影响了。 解决:

  • 检查 VSCode 配置覆盖:打开 VSCode 设置,搜索 settings.json 文件,检查是否有以下设置覆盖了配置文件stylelint.config:{}如果有这个选项,会覆盖.stylelintrc.json 的配置,建议清空。

下载代码提交插件

提交信息校验工具

完整配置流程

安装依赖

# 安装提交信息校验工具
pnpm add @commitlint/cli @commitlint/config-conventional -D
# 安装 Git 钩子工具
pnpm add husky -D
# 安装 lint-staged
pnpm add lint-staged -D
  • @commitlint/cli + @commitlint/config-conventional
    • 作用:校验提交信息是否符合规范格式(如 Angular 规范,要求 type(scope): description 结构)。
    • @commitlint/cli:核心校验工具,提供命令行校验能力。
    • @commitlint/config-conventional:预设的校验规则集(基于 Angular 提交规范,最常用),包含 feat(新功能)、fix(修复)等类型定义。
  • husky
    • 作用:管理 Git 钩子(如 commit-msg 钩子),在提交信息写入时自动触发 commitlint 校验。
    • 没有 husky 时,commitlint 无法自动运行,需要手动执行校验命令,而 husky 可以将校验嵌入到 Git 提交流程中,强制规范。
  • lint-staged
    • 是一个用于在 Git 暂存区(staged)文件上运行脚本的工具。它的核心作用是:只对即将提交的文件执行代码检查或格式化,而不是检查整个项目,从而提高开发效率。
    • 典型使用场景
      • 提交前自动格式化代码:对暂存区的 JS/CSS 文件自动执行 Prettier 格式化
      • 提交前检查代码质量:只对暂存区的文件运行 ESLint/Stylelint,有错误则阻止提交。
      • 自动修复简单问题:对暂存区文件执行 --fix 命令,自动修复可修复的格式问题。

配置

配置 commitlint(校验提交信息格式)

在项目根目录创建 commitlint.config.js 文件,用于定义提交信息的校验规则,如:

export default {
  // 继承的规则
  extends: ["@commitlint/config-conventional"],
  // @see: https://commitlint.js.org/#/reference-rules
  rules: {
    "subject-case": [0], // subject大小写不做校验
    "type-enum": [
      // type枚举
      2,
      "always",
      [
        "build", // 编译相关的修改,例如发布版本、对项目构建或者依赖的改动
        "feat", // 新功能
        "fix", // 修补bug
        "docs", // 文档修改
        "style", // 代码格式修改, 注意不是 css 修改
        "refactor", // 重构
        "perf", // 优化相关,比如提升性能、体验
        "test", // 测试用例修改
        "revert", // 代码回滚
        "ci", // 持续集成修改
        "config", // 配置修改
        "chore", // 其他改动
      ],
    ],
  },
};
配置 husky(管理 Git 钩子)

初始化 husky(需要当前文件夹就是仓库):

pnpx husky install

pnpx 是 pnpm 的包执行工具,等价于 npx。

设置自动启用 husky: 在 package.json 中添加 prepare 脚本(安装依赖后自动启用 husky):

{
  "scripts": {
  "prepare": "husky"
  }
}```

初始化

npx husky init

添加 pre-commit 钩子(触发 lint-staged):

在.husky 目录下 pre-commit 文件输入内容如下:

# 校验暂存区文件
npm run lint:lint-staged

在.husky 目录下添加 commit-msg 文件,内容如下:

# 校验提交信息
npx --no -- commitlint --edit $1
配置 lint-staged(校验暂存区文件)

script 加入 lint:lint-staged 脚本:

"scripts": {
  "lint": "eslint .",
  "lint:fix": "eslint . --fix",
  "lint:lint-staged": "lint-staged",
  // "lint-staged": "lint-staged"
}

在 package.json 中添加 lint-staged 配置(根据项目文件类型调整),例如:

 "lint-staged": {
    "*.{js,ts,vue}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{cjs,json}": [
      "prettier --write"
    ],
    "*.{vue,html}": [
      "eslint --fix",
      "prettier --write",
      "stylelint --fix"
    ],
    "*.{scss,css}": [
      "stylelint --fix",
      "prettier --write"
    ],
    "*.md": [
      "prettier --write"
    ]
  }

执行顺序是:git commit → pre-commit 钩子(lint-staged 工作)→ commit-msg 钩子(commitlint 工作)→ 完成提交。

先保证代码本身质量(lint-staged),再检查提交信息格式(commitlint)