从0到1实践,企业级前端开发底层规范搭建(2024版)

125 阅读13分钟

这是《【Buff叠满】基于Vite+Vue3+TS+AntDV4+unocss+pinia的项目开发底层》的第一篇文章

写在开头

公司用的前端开发底层还是我18年底刚毕业时候搭建的,虽然后续有更新Vue3,再往后就因为工作忙、转岗产品经理导致落下了更新,很多都已经跟不上现在的潮流了

image.png

2023年末,借着公司打算启动新项目的机会研究了几天新东西,发现Vue都到3.4.x了,Antdv都到4.x了,还有unocsspinia等一堆新奇的玩意,瞬间又提起了我的开发梦,于是在拜读了各位大神的文章(见最后引用部分)后,动手一点一点搭建起了通通全新的前端开发底层。

好吧,如果不想看冗长的文章,可以直接出门Gitee下载运行。

环境准备

我使用的是Windows,IDE选用VSCode后续所有的动作都会在这个环境中进行。

Node版本我用的v21.2.0,没错我用的就是这么超前(谁都别拦我),Vite官方推荐18+,小伙伴实测说16+也可以,但我建议还是听官方的吧。

image.png

NVM

你应该听说过nvm,这里简单说一下,这个工具可以帮助你快速安装和切换Node版本,让你方便得从给老板打工切换到提升自己的环境,但如果你的职责就是维护各种时期各种底层的项目的话....这个也很适合你,然后祝你早日脱离苦海🤞

image.png 使用方法和各种指令可参考《nvm 安装、卸载与使用(详细步骤)》

PNPM

关于包管理器,对于巨石项目,每次重新安装依赖都是摸鱼的好机会,时间久还可能安装失败,这里直接推荐使用pnpm来管理项目依赖,列举下优点(直接抄anyup的):

  • 空间共享:在安装依赖时将相同版本的库共享,从而减少磁盘占用。
  • 快速安装:采用符号链接技术,使得安装依赖时速度更快。
  • 并行安装:支持依赖并行安装,提升安装速度。
  • 高效更新:能够通过软连接的方式快速更新依赖。
  • 锁定版本:支持锁定依赖版本,确保在不同开发环境下一致性

总结下就是:**下的快,装的稳,省内存。**截个实测Gif图给你们感受下:

recording.gif 7秒钟809个包你敢信?用就完事了。(更新还老活跃了) 使用方法和各种指令可参考《2022年了,你还没用pnpm吗?》

正式开始

初始化Vue3+TS项目

找到一个干净的你学习的目录(注意是学前端的目录),打开命令行工具,让npm帮我们创建一个全新的vue-ts项目,输入以下指令:

npm create vite@latest vue-ts-app -- --template vue-ts

这里顺便提一嘴, create-vite也可以根据社区优秀的模板创建初始项目,不止Vue。等哪天我这个项目搞定了,大家也可以在github.com/vitejs/awes…这里查看到我这个模板哈哈哈(小小的Flag)。 正常的他会问你要不要装对应依赖,你照做就完事了,不要害怕。

image.png

很快完成后,大家就可以用VSCode打开这个项目,目录如下:

image.png

一览无余,简简单单的毛坯房。不罗嗦,快速把依赖安装好:

recording.gif

看下默认的 npm scripts:

image.png

OK,直接npm run dev:

image.png image.png

到此,一个最基础的Vue+TS项目就搭起来了🎇🎇🎇

代码未动,规范先行

先别急!初始化下Git,保证代码版本不会乱不会丢。

git init

然后把代码规范整好,省的后面一堆报红看着心累。eslint可以保证项目的质量,prettier可以保证项目的统一格式、风格。开整!

Eslint配置

快速安装依赖
pnpm add eslint -D
初始化Eslint
pnpm eslint --init

依次选择合适选项

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

然后等待安装完(pnpm超快的),可以看到根目录多了个.eslintrc.cjs文件

module.exports = {
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:vue/vue3-essential"
  ],
  "overrides": [
    {
      "env": {
        "node": true
      },
      "files": [
        ".eslintrc.{js,cjs}"
      ],
      "parserOptions": {
        "sourceType": "script"
      }
    }
  ],
  "parserOptions": {
    "ecmaVersion": "latest",
    "parser": "@typescript-eslint/parser",
    "sourceType": "module"
  },
  "plugins": [
    "@typescript-eslint",
    "vue"
  ],
  "rules": {
  }
}

package.json的script中添加一个lint命令
  // eslint src 指定lint当前项目中的src文件夹下的文件
  // --ext 为指定lint哪些后缀的文件
  // --fix 开启自动修复
  "eslint": "eslint src --ext .js,.vue,.ts,.jsx,.tsx --ignore-path .gitignore --fix"

执行lint去调用eslint检查代码

pnpm eslint

一般来说不会有问题,如果有问题那就是你的问题了哈哈哈嗝。

去VSCode扩展商店安装Eslint

image.png

完事后在根目录下的.vscode文件夹下创建一个settings.json文件,写上以下代码,实现每次保存代码时,自动执行lint命令来修复代码的错误。

{
    // eslint
    "editor.codeActionsOnSave": {
        "source.fixAll": "never",
        "source.fixAll.eslint": "always"
    },
}

顺手把.gitignore里的这两行删掉,把配置文件也提交上去跟小伙伴们同步。 image.png

Prettier配置

快速安装依赖
pnpm add prettier -D

在根目录下创建.prettierrc.js配置文件,写入我写好的内容,当然你也可以查阅官方文档做自己团队的规范。

/** .prettierrc.js
 * 在VSCode中安装prettier插件 打开插件配置填写`.prettierrc.js` 将本文件作为其代码格式化规范
 * 在本文件中修改格式化规则,不会同时触发改变ESLint代码检查,所以每次修改本文件需要重启VSCode,ESLint检查才能同步代码格式化
 * 需要相应的代码格式化规范请自行查阅配置,下面为默认项目配置
 */
module.exports = {
  // 一行最多多少个字符
  printWidth: 150,
  // 指定每个缩进级别的空格数
  tabWidth: 2,
  // 使用制表符而不是空格缩进行
  useTabs: false,
  // 在语句末尾是否需要分号
  semi: false,
  // 是否使用单引号
  singleQuote: true,
  // 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
  quoteProps: "as-needed",
  // 在JSX中使用单引号而不是双引号
  jsxSingleQuote: false,
  // 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>",默认none
  trailingComma: "es5",
  // 在对象文字中的括号之间打印空格
  bracketSpacing: true,
  // jsx 标签的反尖括号需要换行
  jsxBracketSameLine: false,
  // 在单独的箭头函数参数周围包括括号 always:(x) => x \ avoid:x => x
  arrowParens: "always",
  // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
  rangeStart: 0,
  rangeEnd: Infinity,
  // 指定要使用的解析器,不需要写文件开头的 @prettier
  requirePragma: false,
  // 不需要自动在文件开头插入 @prettier
  insertPragma: false,
  // 使用默认的折行标准 always\never\preserve
  proseWrap: "preserve",
  // 指定HTML文件的全局空格敏感度 css\strict\ignore
  htmlWhitespaceSensitivity: "css",
  // Vue文件脚本和样式标签缩进
  vueIndentScriptAndStyle: false,
  //在 windows 操作系统中换行符通常是回车 (CR) 加换行分隔符 (LF),也就是回车换行(CRLF),
  //然而在 Linux 和 Unix 中只使用简单的换行分隔符 (LF)。
  //对应的控制字符为 "\n" (LF) 和 "\r\n"(CRLF)。auto意为保持现有的行尾
  // 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
  endOfLine: "crlf",
};
package.json的script中添加一个prettier命令
  // eslint . 为指定lint当前项目中的文件
  // --ext 为指定lint哪些后缀的文件
  // --fix 开启自动修复
  "prettier": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",

执行prettier命令即可格式化代码。

VSCode扩展商店安装Prettier - Code formatter插件

image.png

.vscode/settings.json中添加一下规则即可实现保存自动格式化

{
    // 保存的时候自动格式化
    "editor.formatOnSave": true,
    // 默认格式化工具选择prettier
    "editor.defaultFormatter": "esbenp.prettier-vscode"
}

关于Eslint与Prettier的冲突

查阅相关教程的时候发现有作者会发现Eslint跟Prettier会冲突,就是eslint改成了A,prettier又改成了B,导致一直报红。我这其实没有复现,可能是版本最新或者一些未知的原因,反正出现问题大家搜索下快速解决即可。 另外@antfu提出了只用Eslint的方案,因为Eslint既能检查逻辑又能格式化,而Prettier只能格式化且较为死板,友友们可以去了解下,我稍后跟进,具体可看这边文章:《为什么我不使用 Prettier》-antfu

StyleLint配置

Stylelint是针对css的Lint,可检查css语法错误和不合理的写法,指定css书写顺序等。

快速安装依赖

这里以less预处理器为例,其他预处理器如sass、stylus等自行搜索依赖安装嗷!

pnpm add stylelint postcss postcss-less postcss-html stylelint-config-recommended-less stylelint-config-standard stylelint-config-standard-vue stylelint-less stylelint-order -D
依赖说明
快速配置

在根目录下创建.stylelintrc.cjs配置文件,写入以下内容,当然你也可以查阅官方文档做自己团队的规范。

module.exports = {
  extends: [
    'stylelint-config-standard',
    'stylelint-config-recommended-less',
    'stylelint-config-standard-vue'
  ],
  plugins: ['stylelint-order'],
  // 不同格式的文件指定自定义语法
  overrides: [
    {
      files: ['**/*.(less|css|vue|html)'],
      customSyntax: 'postcss-less'
    },
    {
      files: ['**/*.(html|vue)'],
      customSyntax: 'postcss-html'
    }
  ],
  ignoreFiles: [
    '**/*.js',
    '**/*.jsx',
    '**/*.tsx',
    '**/*.ts',
    '**/*.json',
    '**/*.md',
    '**/*.yaml'
  ],
  rules: {
    'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
    'selector-pseudo-element-no-unknown': [
      true,
      {
        ignorePseudoElements: ['v-deep']
      }
    ],
    'selector-pseudo-class-no-unknown': [
      true,
      {
        ignorePseudoClasses: ['deep']
      }
    ],
    // 指定样式的排序
    'order/properties-order': [
      'position',
      'top',
      'right',
      'bottom',
      'left',
      'z-index',
      'display',
      'justify-content',
      'align-items',
      'float',
      'clear',
      'overflow',
      'overflow-x',
      'overflow-y',
      'padding',
      'padding-top',
      'padding-right',
      'padding-bottom',
      'padding-left',
      'margin',
      'margin-top',
      'margin-right',
      'margin-bottom',
      'margin-left',
      'width',
      'min-width',
      'max-width',
      'height',
      'min-height',
      'max-height',
      'font-size',
      'font-family',
      'text-align',
      'text-justify',
      'text-indent',
      'text-overflow',
      'text-decoration',
      'white-space',
      'color',
      'background',
      'background-position',
      'background-repeat',
      'background-size',
      'background-color',
      'background-clip',
      'border',
      'border-style',
      'border-width',
      'border-color',
      'border-top-style',
      'border-top-width',
      'border-top-color',
      'border-right-style',
      'border-right-width',
      'border-right-color',
      'border-bottom-style',
      'border-bottom-width',
      'border-bottom-color',
      'border-left-style',
      'border-left-width',
      'border-left-color',
      'border-radius',
      'opacity',
      'filter',
      'list-style',
      'outline',
      'visibility',
      'box-shadow',
      'text-shadow',
      'resize',
      'transition'
    ]
  }
}
package.json的script中添加一个lint命令
  "lint:style": "stylelint \"./**/*.{css,less,vue,html}\" --fix"

执行lint去调用eslint检查代码

pnpm lint:style
VSCode扩展商店安装Stylelint插件

image.png

.vscode/settings.json中添加一下规则即可实现保存自动格式化

{
    // 保存的时候自动格式化Style
    "stylelint.validate": ["css", "less", "vue", "html"]
}

试一下

recording.gif

完美!

Commitizen配置

团队协作中除了代码,免不了用Git进行版本控制和协同开发,但不是每个开发者在提交的时候都会认真书写,导致回溯代码版本时候摸不着头脑...举个5年前团队项目的例子...

image.png

所以清晰且统一的提交描述(Commit message)风格,能够降低协作项目的维护成本,提高合作开发效率。使用Commitizen即可帮助我们设定一个标准。

快速安装依赖

安装commitizen和其适配器cz-conventional-changelog

pnpm add commitizen cz-conventional-changelog -D
package.json的script中添加一个lint命令
"commit": "git-cz"
package.json中添加一个config配置
  "config": {
    "commitizen": {
      "path": "cz-conventional-changelog"
    }
  }
使用流程

配置好之后,就可以用pnpm commit代替之前的git commit了!执行命令后就会出现标准的提交类型选项,照着填就行。

image.png

Husky配置

最后再上一道保险,代码提交前的强制校验,保证那些没有按规定规范书写的老鼠屎代码不会坏了整锅前端项目粥,另外还能规范提交描述,属于团队协作必备的检验流程。 哈士奇Hasky可以为 Git 客户端增加钩子(hooks)功能,让你在特定事件(如 commit、push)发生时触发自定义的代码审查、自动化测试、提交描述规范等任务。

Husky安装和配置

安装依赖(注意是安装V8版本,先别安装最新的,配置不太一样嗷!)

pnpm add husky@8.0.3 -D
package.json的script中添加一个prepare命令
"prepare": "husky install"

prepare脚本是 npm 的特殊脚本之一,它在npm install命令之后执行,这样项目的其他同学在装包的时候就会自动执行该命令来执行husky安装。 直接执行pnpm prepare,根目录会多一个.husky目录,然后运行以下husky命令添加pre-commit钩子。

pnpm husky .husky/pre-commit "pnpm eslint && pnpm prettier && pnpm lint:style"

执行后会在.husky目录下生成一个pre-commit文件。当git commit的时候就会执行pnpm eslintpnpm prettier,如果命令出现报错,就不会提交成功,以此来保证提交代码的质量和格式规范!

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

pnpm eslint && pnpm prettier && pnpm lint:style

试一下,发现Eslint的逻辑报错能够终止git提交了

recording.gif

不过要注意的是,仅Eslint报的错误会终止Git提交,如果Eslint没问题,stylelint有问题,则会出现提交成功然后再自动修复的问题,导致提交上去的代码仍然是有问题的。解决方案就是用Lint-stage

Lint-staged安装和配置

lint-staged可以在git staged阶段的文件上执行代码检查(Linters),包括ESLint和Stylelint等。好处是你可以通过设置只检查通过git add添加到暂存区的文件,避免每次检查都把整个项目的代码都检查一遍,从而提高效率,避免不必要的耗时。

安装依赖
pnpm add lint-staged -D
在package.json的script中添加一个pre-commit命令
"pre-commit": "lint-staged"
新建 .lintstagedrc配置文件并添加以下命令
{
  "src/**/*.{html,vue,ts,js,json,md}": [
    "prettier --write",
    "eslint --fix",
    "stylelint --fix"]
}
修改.husky/pre-commit文件,提交时执行lint-staged
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

pnpm run pre-commit

试一下,没问题!自动修复了。

recording.gif

commitlint安装和配置

最后再顺手把提交描述也规范下,术语叫“约定式提交(Conventional Commits)”,commit-msg可以帮助我们检查提交的消息是否符合规定,回看提交记录的时候不会头皮发麻。

安装依赖
pnpm add @commitlint/config-conventional @commitlint/cli -D
根目录下新建.commitlint.config.cjs配置文件:
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [ // type枚举
        2, 'always',
        [
          'build', // 编译相关的修改,例如发布版本、对项目构建或者依赖的改动
          'feat', // 新功能
          'fix', // 修补bug
          'docs', // 文档修改
          'style', // 代码格式修改, 注意不是 css 修改
          'refactor', // 重构
          'perf', // 优化相关,比如提升性能、体验
          'test', // 测试用例修改
          'revert', // 代码回滚
          'ci', // 持续集成修改
          'config', // 配置修改
          'chore', // 其他改动
        ],
    ],
    'type-empty': [2, 'never'], // never: type不能为空; always: type必须为空
    'type-case': [0, 'always', 'lower-case'], // type必须小写,upper-case大写,camel-case小驼峰,kebab-case短横线,pascal-case大驼峰,等等
    'scope-empty': [0],
    'scope-case': [0],
    'subject-empty': [2, 'never'], // subject不能为空
    'subject-case': [0],
    'subject-full-stop': [0, 'never', '.'], // subject以.为结束标记
    'header-max-length': [2, 'always', 72], // header最长72
    'body-leading-blank': [0], // body换行
    'footer-leading-blank': [0, 'always'], // footer以空行开头
  }
}
package.json的script中添加一个commitlint命令
"commitlint": "commitlint --config .commitlint.config.cjs -e -V"
运行以下husky命令添加commit-msg钩子
pnpm husky add .husky/commit-msg "npm run commitlint"

参考文献

(我也不知道他们参考的谁的)