Vite + Vue3实现前端项目工程化Vue3发布至今,周边的生态、技术方案已足够成熟,项目可切换到Vite + Vu
Vue3发布至今,周边的生态、技术方案已足够成熟,项目可切换到Vite + Vue3了。今天就给大家操作下这种技术方案实现前端工程化。
初始化项目
通过官方脚手架初始化项目
- 第一种方式:使用vite命令创建,这种方式除了可以创建vue项目,还可以创建其他类的项目,比如react项目。
npm init vite@latest
- 第二种方式:这种方式是vite专门为vue做的配置,这种方式创建的项目在创建时会提示是否需要安装各种插件配置。
npm init vue@latest
- 第三种方式:直接快速通过参数生成
npm init vite@latest project-engineer --template vue-ts
询问的相关问题:
Project name: .... // 项目名称,默认值:vue-project,可输入想要的项目名称,此处不建议中文。
Add TypeScript? ... No / Yes // 是否加入TypeScript组件?
Add JSX Support? ... No / Yes // 是否加入JSX支持?
Add Vue Router for Single Page Application development? ... No / Yes // 是否为单页面应用程序开发添加Vue Router路由管理组件?
Add Pinia for state management? ... No / Yes //是否添加Pinia组件来进行状态管理?
Add Vitest for Unit Testing? ... No / Yes //是否添加Vitest来进行单元测试?
Add an End-to-End Testing Solution? >> No //是否添加一个端到端测试解决方案?
Add ESLint for code quality? ... No / Yes //是否添加ESLint来进行代码质量检查?
Add Prettier for code formatting? ... No / Yes //是否添加Prettier代码格式化?
执行结束后进行项目目录,安装依赖后执行 npm run dev 即可秒开项目。
命令行演示操作
生成的项目目录如下:
但此项目录不足以支持项目的复杂度,因此对目录结构进行扩展如下:
定制化plugins
在初始化的项目中vite.config.js指示引入了提供Vue3单文件组件支持的plugin,大家可以根据项目需要进行个性化配置,详见awesome-vite。
1. @vitejs/plugin-vue-jsx
提供Vue3 JSX & TSX支持(通过专用的Babel转换插件)。
安装
npm i -D @vitejs/plugin-vue-jsx
配置vite.config.ts
import { defineConfig } from 'vite'
import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins:[
vueJsx({
// options参数将传给@vue/babel-plugin-jsx
}),
],
})
2. rollup-plugin-visualizer
可视化并分析构建包,查看哪些模块占用空间大小,以此来优化构建包的大小。这是一个Rollup 的plugin,推荐这个也是vite的一个特性,vite默认已经支持大部分的Rollup的plugin,从这点来看,vite的plugin库更加丰富了。
安装
npm i -D rollup-plugin-visualizer
配置vite.config.ts
import { defineConfig } from 'vite'
import visualizer from 'rollup-plugin-visualizer'
export default defineConfig({
plugins:[visualizer()]
})
- vite-plugin-element-plus
为ElementPlus提供按需进入能力。全量导入ElementPlus导致构建包的体积过大,按需引入有效的减小包的体积。此包的原理是动态将每个按需引入的组件css写入。
import { ElButton } from 'element-plus'
import 'element-plus/es/components/button/style/css'
安装
npm i -D vite-plugin-element-plus
配置vite.config.ts
import { defineConfig } from 'vite'
import importElementPlus from 'vite-plugin-element-plus'
export default defineConfig({
plugins: [
// @ts-ignore 此处暂时需要使用 ignore
// 原因是包内部的 options 未做非必填兼容
// 目前已有人提了 PR,未合并,使用可以观望下
importElementPlus(),
],
})
基于husky + lint-staged项目规范化
- Husky支持所有Git钩子,当你提交或推送时,你可以使用husky来检查你的提交消息、运行测试、检查代码等。安装后,它会自动在仓库中.git/ 目录下增加相应的钩子,比如 pre-commit钩子就会在你执行 git commit 的触发。那么我们可以在pre-commit中实现一些比如lint检查、单元测试、代码优化等操作。当然,pre-commit阶段执行的命令当然要保证其速度不要太慢,每次commit都等很久也不是什么好的体验。
- lint-staged,一个过滤出Git代码暂存区文件(被 git add的文件)的工具。这个很实用,因为我们如果对整个项目的代码做一个检查,可能耗时很长,如果是老项目,要对之前的代码做一个代码规范检查并修改的话,这可能就麻烦了呀,可能导致项目改动很大。所以lint-staged,对团队项目和开源项目来说,是一个很好的工具,它是对个人要提交的代码的一个规范和约束。
1. ESLint
eslint用于配置代码风格、质量的校验,prettier用于代码格式的校验,lint-staged过滤文件。
本项目已经默认安装eslint、prettier,如果需要单独安装,执行以下命令:
# 安装 eslint
npm i eslint -D
# 利用 eslint 命令行工具生成基本配置
npx eslint --init
生成的.eslintrc.cjs文件,如下:
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
}
}
做一下配置补充
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true
},
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
},
plugins: ['@typescript-eslint'],
rules: {}
}
这里为什么生成的配置文件名称是.eslintrc.cjs而不是.eslintrc.js? 因为我们将项目定义为ESM,eslint --init会自动识别type,并生成兼容的配置文件名称,如果我们改回.js结尾,在运行eslint将会报错。出现这个问题eslint内部使用了require()语法读取配置。
同样,这个问题也适用于其他功能的配置,比如后面会提到的Prettier、Commitlint等,配置文件都不能以xx.js结尾,而要改为当前库支持的其他配置文件格式,如:.xxrc、.ssrc.json、.ssrc.yml。
验证配置是否生效,在任意组件脚本中定义如下代码:
const calc = (a:number, b:number) => {
return a +b
}
// console.log(calc(10, 20))
执行package.json中的lint命令(没有的话需要自行配置,package.json指令配置如下)
注释上面打印信息的情况下,执行npm run lint指令,将会出现1条错误提示信息
注释放开后,变量被调用,再次执行指令则校验通过。
2. Prettier
Prettier如果需要单独安装,执行以下命令:
# 安装 prettier
npm i prettier -D
.prettier.json默认配置如下(没有这个文件的需要自行创建)
{
"$schema": "https://json.schemastore.org/prettierrc",
"semi": false,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 100,
"trailingComma": "none"
}
- semi:false 句末是否使用分号(false | true)
- singleQuote:true 是否使用单引号代替双引号(false | true)
- trailingComma:'none' 最后一个对象元素是否加逗号,'none'为不加
- tabWidth 设置工具每一个水平缩进的空格数
- printWidth 换行字符串阙值
- bracketSpacing:true 对象,数组是否加空格(false | true)
- jsxBracketSameLine:true jsx > 是否另起一行(false | true)
- arrowParens:'always'(x) => {}是否要有小括号,值为'always'则需要
- requirePragma:false 是否需要写文件开头的@prettier(false | true)
- insertPragma:false 是否需要自动在文件开头插入@prettier
3. Prettierrc & ESLint规则冲突的解决
上面提到过,eslint用于配置代码风格、质量校验,prettier用于代码格式的校验,lint-staged过滤文件。
但两者在使用过程中,会因为规则不同,有出现冲突的可能性,所以需要通过插件加强两者的配合:
- eslint-plugin-prettier一个ESLint插件,由prettier生态提供,用于关闭可能与prettier冲突的规则
- eslint-config-prettier使用prettier代替eslint格式化,防止Prettier和ESLint的自动格式化冲突
安装
# 带 lint-staged
npm i eslint prettier lint-staged eslint-plugin-prettier eslint-config-prettier -D
# 不带 lint-staged(本文采用方式)
npm i eslint-config-prettier eslint-plugin-prettier -D
.eslintrc.cjs配置文件
控制台执行 npm run lint可以做代码校验和格式化了(Vite+Vue3项目搭建时选择了eslint、prettier配置的情况下,默认配置已够用,可根据需要做增项)
完成了eslint和prettier的集成配置,无论你使用了什么编辑器,有没有安装相关插件,都不会影响代码校验的效果。
4. Husky
因为一个项目通常是团队合作,我们不能保证每个人在提交代码前都执行了一遍lint校验,所以需要 git hooks来自动化校验的过程,否则禁止提交。
# 安装 husky
npm i husky -D
# 生成 .husky 文件夹(注意:这一步操作之前,一定要执行 git init 初始化当前项目仓库,.husky 文件夹才能创建成功)
npx husky-init install
在package.json中添加'prepare'指令
"scripts":{
// 省略其它指令
"prepare":"husky install"
}
.husky/pre-commit文件修改如下
#!/user/bin/env sh
."$(dirname -- "$0")/_/husky.sh"
npm run lint
测试钩子(git hooks)是否生效
修改组件代码(变量声明调用和不调用两种情况),执行如下git命令提交代码,查看结果
git add
git commit -m "测试husky"
变量声明未调用
const calc = (a:number,b:number):number => {
return a + b
}
// console.log(calc(1024,28))
执行结果
当git commit 时,它会自动检测到不符合规范的代码,如果无法自主修复就会抛出错误提示。
变量声明并调用
const calc =(a:number,b:number):number => {
return a + b
}
console.log(calc(1024,28))
执行结果
5. Commitlint
为什么需要Commitlint,除了在后续生成的changelog文件和语义发版中需要提取commit中的信息外,也利于其它团队开发者分析你提交的代码,所以我们要约定commit的规范。
安装如下两个插件:
- @commitlint/cli Commitlint命令行工具
- @commitlint/config-conventional基于Angular的约定规范
npm i @commitlint/config-conventional @commitlint/cli -D
最后将Commitlint添加到钩子:
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
创建.commitlintrc,并写入配置
{
"extends": [
"@commitlint/config-conventional"
]
}
注意:这里配置文件名使用的是.commitlintrc而不是默认的.commitlintrc.js
测试Commitlint是否生效,与上面同样的方式提交“符合规范和不符合规范的代码”,查看结果。
转载自:https://juejin.cn/post/7309786535934492672