赞
踩
结合了很多项目和文章,总结一篇项目构建的笔记
温馨提示:文章末尾记录了我在搭建项目过程中,遇到的一些问题和解决办法 ~
我是用的是当前最新的稳定版
1、执行 npm create vite@latest
创建项目
2、按照以下步骤,选择创建vue项目,使用TypeScript语言。
如下输出,就说明项目创建成功了。
创建项目名称——vue3-ts-test
使用的框架:Vue3
使用的语言:TypeScript
用vscode打开项目
npm install
下载初始化依赖包
npm run dev
运行项目
----|src --------|api # 接口请求目录 --------|assets # 静态资源目录 --------|axios # axios封装目录 ----------|service.ts --------|components # 公共组件目录 --------|hooks # vue3-hooks函数目录 --------|locales # 语言版本目录 ----------|en # 英文版本 ------------|index.ts # ----------|zh # 中文版本 ------------|index.ts # --------|router # 路由配置目录 --------|store # 状态管理目录 --------|types # 集中管理类型 --------|utils # 工具函数目录 --------|views # 页面组件目录 ----|App.vue ----|main.ts ----|.env.development ----|.env.production ----|.env.test ----|package.json ----|vite.config.ts
1、配置开发、线上和测试环境
.env.development
NODE_ENV = "development"
# 是否兼容旧的浏览器
VITE_LEGACY = false
# 开发环境网站前缀
VITE_BASE_URL = /
# 开发环境后端地址
VITE_BASE_API = "http://xx.xx.xx.xx:xxxx/"
.env.production
# 线上环境
NODE_ENV = "production"
# 是否兼容旧的浏览器
VITE_LEGACY = false
# 线上环境网站前缀
VITE_BASE_URL = /
# 线上环境后端地址
VITE_BASE_API = "http://xx.xx.xx.xx:xxxx/"
.env.test
# 测试环境
NODE_ENV = "test"
# 是否兼容旧的浏览器
VITE_LEGACY = false
# 测试环境网站前缀
VITE_BASE_URL = /
# 测试环境后端地址
VITE_BASE_API = "http://xx.xx.xx.xx:xxxx/"
2、安装cross-env
cross-env:运行跨平台设置和使用环境变量的脚本
windows不支持NODE_ENV=development的设置方式。这个迷你的包(cross-env)能够提供一个设置环境变量的scripts,让你能够以unix方式设置环境变量,然后在windows上也能兼容运行。
npm install cross-env --save-dev
3、配置package.json
"scripts": {
"dev": "vite",
"dev-prod": "vite --mode production",
"dev-test": "vite --mode test",
"build": "vue-tsc && vite build",
"build:prod": "cross-env NODE_ENV=production BASE_ENV=production webpack -c build/webpack.prod.js",
"build:test": "cross-env NODE_ENV=test BASE_ENV=test webpack -c build/webpack.test.js",
"preview": "vite preview"
},
1、修改文件内容如下
import { loadEnv } from 'vite' import type { UserConfig, ConfigEnv } from 'vite' import vue from '@vitejs/plugin-vue' // 如果编辑器提示 path 模块找不到,需要安装一下 @types/node --> npm i @types/node -D import { resolve } from 'path' // https://vitejs.dev/config/ export default ({ command, mode }: ConfigEnv): UserConfig => { const { VITE_BASE_URL, VITE_BASE_API } = loadEnv( mode, process.cwd() ) return { base: VITE_BASE_URL, plugins: [vue()], resolve: { alias: { //设置'@'指向'src'目录 '@': resolve(__dirname, './src') }, extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"] }, server: { port: 8089, //设置服务启动端口号 open: true, //设置服务启动后是否自动打开浏览器 cors: true, //允许跨域 //设置代理 proxy: { '/api': { target: VITE_BASE_API, //设置代理目标 changeOrigin: true, //是否修改目标源 // rewrite: (path) => path.replace(/^\/api/, '') //设置路径重写 } } } } }
2、安装@types/node 模块,在 tsconfig.json 中设置 paths
npm i @types/node -D
{
"compilerOptions": {
...
"noFallthroughCasesInSwitch": true,
"paths": {
"@/*": [
"./src/*"
]
}
},
}
3、在vite.config.ts中添加如下配置
import { resolve } from 'path'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': resolve(__dirname, './src')
},
extensions: [".mjs", ".js", ".ts", ".jsx", ".tsx", ".json", ".vue"]
}
})
1、安装vue-router
npm i vue-router@4
2、测试路由案例:
(1)创建src/views/Login.vue文件
<template> <div @click="toLogin">登录</div> </template> <script lang="ts" setup> import { useRouter } from 'vue-router' const router = useRouter() function toLogin() { console.log('登录ing'); router.push({ name: 'dataAll' }) } </script>
(2)创建src/views/DataAll.vue文件
<template>
<div @click="toLogin">
首页
</div>
</template>
<script>
function toLogin() {
console.log('首页ing');
}
</script>
(3)创建 src/router/index.ts 文件
// 路由配置文件 import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router' const routes: Array<RouteRecordRaw> = [ { path: '/', redirect: '/login' }, { path: '/login', name: 'login', component: () => import('@/views/Login.vue') // 懒加载组件 }, { path: '/dataAll', name: 'dataAll', component: () => import('../views/DataAll.vue') // 懒加载组件 }, ] const router = createRouter({ scrollBehavior: () => ({ left: 0, top: 0 }), history: createWebHashHistory(), routes }) // router.beforeEach((to, from, next) => { // next() // }) export default router
(4)在main.ts文件中挂载路由配置
import { createApp } from 'vue'
import App from './App.vue'
// 挂载路由
import router from './router/index'
createApp(App).use(router).mount('#app')
(5)在App.vue中设置 routerview
<script setup lang="ts">
</script>
<template>
<router-view></router-view>
</template>
<style scoped></style>
1、安装pinia和pinia-plugin-persistedstate
npm i pinia
npm i pinia-plugin-persistedstate //pinia持久化插件
2、创建 src/store/index.ts 文件
说明:main.ts里的createPinia直接在store里面做,包括引入持久化插件 省去main.ts的冗余
import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate' //导入持久化插件
// 创建pinia实例
const pinia = createPinia()
// 使用pinia插件
pinia.use(persist)
// 导出pinia实例,给main使用
export default pinia
3、在main.ts文件中挂载pinia配置
import { createApp } from 'vue'
import App from './App.vue'
// 挂载路由
import router from './router/index'
// 挂载pinia
import pinia from './store'
createApp(App).use(router).use(pinia).mount('#app')
4、测试pinia案例:
src/store/useUser.ts
import { defineStore, acceptHMRUpdate } from "pinia"; import type { IUserInfo } from '../types/user'; import { ref } from 'vue'; export const useUserStore = defineStore('user', () => { // 用户信息 const user = ref<IUserInfo>() // 设置用户,登录后使用 const setUser = (u: IUserInfo) => { user.value = u } // 清空用户,退出后使用 const delUser = () => { user.value = undefined } return { user, setUser, delUser } }, { persist: true // 开启持久化 }) if (import.meta.hot) { import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot)) }
注意:这里有个import.meta.hot判断作用如下:
Pinia 是 vuex 新替代方案。Pinia 中热更新实现,借助 import.meta
热更新:(Hot Module Replacement,简写 HMR)代码会自动更新页面。当修改代码时,HMR能够在不刷新页面的情况下,把页面中发生变化的模块,替换成新的模块,同时不影响其他模块的正常运作。
Pinia 支持热更新,所以你可以编辑你的 store,并直接在你的应用中与它们互动,而不需要重新加载页面,允许你保持当前的state、并添加甚至删除state、actions和getters。
目前,只有Vite被官方支持,不过任何实现import.meta.hot规范的构建工具都应该能正常工作。你只需要在任何 store 声明旁边添加这段代码。比方说,你有三个 store:auth.js、cart.js和chat.js,你必须在每个 store 声明后都添加(和调整)这段代码即可。if (import.meta.hot) { import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot)) }
- 1
- 2
- 3
代码中引入的src/types/user.ts
src/views/DataAll.vue
<template> <div @click="toLogin"> 首页 </div> <h1 @click="btnName"> 点我显示姓名-{{ store.user?.nickname }} </h1> </template> <script lang="ts" setup> import { useUserStore } from '../store/useUser.ts' const store = useUserStore() function btnName() { console.log('点我显示姓名'); store.setUser({ id: 0, avatar: '123', nickname: '啊叼吖' }) } function toLogin() { console.log('首页ing'); } </script>
1、安装Sass
npm i sass -D
2、创建/assets/common.scss文件(common.scss文件里的内容根据自己的需求配置)
*, *::before, *::after { box-sizing: border-box; margin: 0; position: relative; font-weight: normal; } body { min-height: 100vh; color: var(--color-text); background: var(--color-background); transition: color 0.5s, background-color 0.5s; line-height: 1.6; font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; font-size: 15px; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
3、在main.ts中引入./assets/common.scss
import { createApp } from 'vue'
import App from './App.vue'
// 挂载路由
import router from './router/index'
// 挂载pinia
import pinia from './store'
import './assets/common.scss'
createApp(App).use(router).use(pinia).mount('#app')
4、如果想在js代码中使用scss变量怎么引入?
举例说明:想让src/assets/css/variables.scss中的变量在js中使用
(1)variables.scss内容:
// base color $white: #fff; $black: #181818; $grey: #dcdfe6; $bg-grey: #f0f1f5; $greyActive: #c0c4cc; $red: #ff4949; $redActive: #f56c6c; $green: #13ce66; $greenActive: #42d885; $blue: #1890ff; $blueActive: #46a6ff; // chart color $chartBlue: #3aa0ff; $chartRed: #f2637b; $chartYellow: #fad337; $chartGreen: #4ecb73; $chartBrown: #e9a674; $chartCyan: #36cbcb; :export { white: $white; black: $black; grey: $grey; bg-grey: $bg-grey; greyActive: $greyActive; red: $red; redActive: $redActive; green: $green; greenActive: $greenActive; blue: $blue; blueActive: $blueActive; chartBlue: $chartBlue; chartRed: $chartRed; }
(2)创建src/assets/css/global.module.scss:
//在global.module.scss中引入variables.scss @import './variables.scss'; //并暴露出variables.scss里的变量 :export { white: $white; black: $black; grey: $grey; bg-grey: $bg-grey; greyActive: $greyActive; red: $red; redActive: $redActive; green: $green; greenActive: $greenActive; blue: $blue; blueActive: $blueActive; chartBlue: $chartBlue; chartRed: $chartRed; }
(3)在想要使用variables.scss变量的文件里引入:
import variables from '@/assets/css/global.module.scss'
import { onMounted } from 'vue'
onMounted(() => {
console.log(variables.black)
})
1、安装vite-plugin-svg-icons
npm i vite-plugin-svg-icons
2、在vite.config.ts中配置
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' import { loadEnv } from 'vite' import type { UserConfig, ConfigEnv } from 'vite' import vue from '@vitejs/plugin-vue' // 如果编辑器提示 path 模块找不到,需要安装一下 @types/node --> npm i @types/node -D import { resolve } from 'path' // https://vitejs.dev/config/ export default ({ command, mode }: ConfigEnv): UserConfig => { const { VITE_BASE_URL, VITE_BASE_API } = loadEnv( mode, process.cwd() ) return { base: VITE_BASE_URL, plugins: [ vue(), createSvgIconsPlugin({ // 图标文件夹路径 iconDirs: [resolve(process.cwd(), 'src/assets/icons')], // 符合该格式的唯一标识符,用于创建对应的 SVG 图标 symbolId: '[name]', // 将生成的 SVG 图标注入到文档中的位置 inject: 'body-last', // 自定义的 DOM 元素 ID customDomId: '__svg__icons__dom__' }) ], resolve: { alias: { //设置'@'指向'src'目录 '@': resolve(__dirname, 'src') } }, server: { port: 8089, //设置服务启动端口号 open: true, //设置服务启动后是否自动打开浏览器 cors: true, //允许跨域 //设置代理 proxy: { '/api': { target: VITE_BASE_API, //设置代理目标 changeOrigin: true, //是否修改目标源 // rewrite: (path) => path.replace(/^\/api/, '') //设置路径重写 } } } } }
3、在main.ts中引入
import 'virtual:svg-icons-register'
4、测试svg插件案例:
在这个文件夹下src/assets/icons添加svg图片
新建svg封装组件src\components\svgIcon\index.vue
<template> <svg :class="svgClass" aria-hidden="true"> <use class="svg-use" :href="symbolId" /> </svg> </template> <script lang="ts"> import { defineComponent, computed } from 'vue' export default defineComponent({ name: 'SvgIcon', props: { prefix: { type: String, default: 'icon' }, name: { type: String, required: true }, className: { type: String, default: '' } }, setup(props) { const symbolId = computed(() => `#${props.name}`) const svgClass = computed(() => { if (props.className) { return `svg-icon ${props.className}` } return 'svg-icon' }) return { symbolId, svgClass } } }) </script> <style scope> .svg-icon { vertical-align: -0.1em; /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */ fill: currentColor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */ overflow: hidden; } </style>
在页面中使用
<template>
<SvgIcon name="username" />
</template>
<script lang="ts" setup>
import SvgIcon from '@/components/svgIcon/index.vue'
</script>
1、安装Element Plus
npm i element-plus
2、在main.ts文件中挂载Element Plus配置
import { createApp } from 'vue'
import App from './App.vue'
// 挂载路由
import router from './router/index'
// 挂载pinia
import pinia from './store'
// 引入全局公共样式
import './assets/common.scss'
// 挂载Element Plus
import ElementPlus from 'element-plus'
//一定要记得引入element的css样式!!!
import 'element-plus/dist/index.css'
createApp(App).use(router).use(pinia).use(ElementPlus).mount('#app')
3、使用方式:
src/views/DataAll.vue
<template> <div @click="toLogin"> 首页 </div> <h1 @click="btnName"> 点我显示姓名-{{ store.user?.nickname }} </h1> <div class="block"> <span class="demonstration">Picker with quick options</span> <el-date-picker v-model="value2" type="date" placeholder="Pick a day" :disabled-date="disabledDate" :shortcuts="shortcuts" :size="size" /> </div> </template> <script lang="ts" setup> import { useUserStore } from '../store/useUser.ts' import { ref } from 'vue' const store = useUserStore() const value2 = ref('') function btnName() { console.log('点我显示姓名'); store.setUser({ id: 0, avatar: '123', nickname: '啊叼吖' }) } function toLogin() { console.log('首页ing'); } const shortcuts = [ { text: 'Today', value: new Date(), }, { text: 'Yesterday', value: () => { const date = new Date() date.setTime(date.getTime() - 3600 * 1000 * 24) return date }, }, { text: 'A week ago', value: () => { const date = new Date() date.setTime(date.getTime() - 3600 * 1000 * 24 * 7) return date }, }, ] const disabledDate = (time: Date) => { return time.getTime() > Date.now() } </script> <style scoped> .demo-date-picker { display: flex; width: 100%; padding: 0; flex-wrap: wrap; } .demo-date-picker .block { padding: 30px 0; text-align: center; border-right: solid 1px var(--el-border-color); flex: 1; } .demo-date-picker .block:last-child { border-right: none; } .demo-date-picker .demonstration { display: block; color: var(--el-text-color-secondary); font-size: 14px; margin-bottom: 20px; } </style>
1、安装axios
npm i axios
2、配置axios
src/axios/service.ts
import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios' import { ElMessage } from 'element-plus' // 创建axios实例 进行基本参数配置 const service = axios.create({ // 默认请求地址,根据环境的不同可在.env 文件中进行修改 baseURL: '/api', // 设置接口访问超时时间 timeout: 30000, // request timeout, // 设置请求头中的请求内容类型 headers: { 'Content-Type': 'application/json;charset=utf-8' }, // 跨域时候允许携带凭证 withCredentials: true }) // request interceptor 接口请求拦截 service.interceptors.request.use( (config: InternalAxiosRequestConfig) => { return config }, (error: AxiosError) => { // 请求错误,这里可以用全局提示框进行提示 return Promise.reject(error) } ) // response interceptor 接口响应拦截 service.interceptors.response.use( (response: AxiosResponse) => { const code: number = response.data.code if (code !== 200) { ElMessage({ type: 'error', message: response.data.message }) return Promise.reject(response.data) } return response.data }, (error: AxiosError) => { ElMessage({ type: 'error', message: error.message }) return Promise.reject(error) } ) export default service
OK~ 到这里项目结构和集成工具基本都配置完了,下面是一些代码规范管理。
1、安装eslint
npm i eslint -D
2、初始化eslint
npx eslint --init
3、按照终端提示操作,完成之后的配置
4、上一个最后一步执行No,然后手动npm安装提示的依赖
npm i -D eslint-plugin-vue@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
5、初始化完成后会在项目根目录下看到一个.eslintrc.cjs的文件,这个文件就是eslint的配置文件。
.eslintrc.cjs
module.exports = { "env": { "browser": true, "es2021": true, "node": 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": { } }
6、在package.json,添加命令
"scripts": {
// 执行该命令eslint会检测当前项目下所有的.vue,.js,.ts,.jsx,.tsx文件是否符合eslint的代码规范,并尝试自动修复
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix"
},
执行npm run lint
命令,可能会有如下报错
修改.eslintrc.cjs 文件
module.exports = { "env": { "browser": true, "es2021": true, "node": 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": { "@typescript-eslint/ban-types": [ "error", { "extendDefaults": true, "types": { "{}": false } } ] } }
然后重新执行npm run lint
命令就不会报错了。
7、在vscode中安装ESLint插件
ESLint:这个插件会自动查找项目中的ESlint规则,给出验证提示,ESlint也可以对代码进行格式化。
1、安装Prettier
npm i prettier -D
2、创建并配置Prettier配置文件
prettier.config.cjs:
// prettier的默认配置文件 module.exports = { // 一行最多 100 字符 printWidth: 100, // 使用 2 个空格缩进 tabWidth: 2, // 不使用缩进符,而使用空格 useTabs: false, // 不尾随分号 semi: false, // 使用单引号 singleQuote: true, // 多行逗号分割的语法中,最后一行不加逗号 trailingComma: 'none', // 单个参数的箭头函数不加括号 x => x arrowParens: 'avoid', // 对象大括号内两边是否加空格 { a:0 } bracketSpacing: true, }
3、在vscode中安装Prettier - Code formatter插件
Prettier - Code formatter:这个插件会对代码进行格式化,但并不关注代码质量潜在问题的检查。
4、配置VScode保存时自动格式化代码
修改vscode的配置文件,在 settings.json 中添加以下内容:
{ // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsize "editor.tabSize": 2, // 每次保存的时候自动格式化 "editor.formatOnSave": true, "editor.codeActionsOnSave": { // 使用eslint来fix,包括格式化会自动fix和代码质量检查会给出错误提示 "source.fixAll.eslint": true }, // 把prettier设置为vscode默认的代码格式化工具 "editor.defaultFormatter": "esbenp.prettier-vscode", // vue文件的默认格式化工具选择prettier "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }
配置到这里当我们在vscode编辑器中保存代码时,就可以自动格式化代码了!
1、冲突的原因:
eslint 检测代码规范、pretter 修复代码格式,我们在setttings.json文件中同时开启了ESLint和Prettier进行代码格式化,两者的格式化规则有一些重叠。在配置不当情况下,比如 eslint 设置单引号、prettier 双引号,会导致编译执行错误,导致冲突。
2、解决冲突:
安装 eslint-config-prettier 和 eslint-plugin-prettier 依赖:
npm install eslint-config-prettier eslint-plugin-prettier -D
eslint-config-prettier 会关闭ESLint中有关代码格式化的配置;
eslint-plugin-prettier 把Prettier配置成ESLint的一个插件,让其当做一个linter规则来运行;
然后在 .eslintrc.cjs 中 extends的最后添加一个配置:
extends: [
'eslint:recommended',
'plugin:vue/vue3-essential',
'plugin:@typescript-eslint/recommended',
"plugin:prettier/recommended" // 解决ESlint和Prettier冲突
],
这样配置后,ESLint进行格式化时就会忽略跟Prettier重叠的格式规则,这些交由Prettier来进行格式化,这样就解决了ESlint和Prettier的冲突问题了。
3、配置vite运行的时候自动检测eslint规范
vite运行的时候默认是不会自动检测eslint规范的,而执行npm run lint
命令时却可以看到有eslint的警告信息。
如果想要vite运行的时候自动检测eslint规范,只需要安装vite-plugin-eslint依赖和添加相关配置即可。
安装vite-plugin-eslint:
npm install vite-plugin-eslint -D
配置 vite.config.ts文件:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
// 配置vite在运行的时候自动检测eslint规范
eslintPlugin({
include: ['src/**/*.ts', 'src/**/*.js', 'src/**/*.vue', 'src/*.ts', 'src/*.js', 'src/*.vue']
})
]
})
在vite.config.ts文件中添加了vite-plugin-eslint插件的配置后,运行项目的时候就会看到对代码进行eslint规范检查了。
husky 是一个 Git 钩子(Git hooks)工具,它可以在项目中植入你设定的 git hooks,在 git 提交代码的前后,你预设的 git hooks 可以得到执行,以对代码、文件等进行预设的检查,一旦检查不通过,就可以阻止当前的代码提交,避免了不规范的代码和 git 提交出现在项目中。
lint-staged 是一个专门用于在通过 git 提交代码之前,对暂存区的代码执行一系列的格式化。当 lint-staged 配合 git hooks 使用时,可以在 git 提交前的 hook 中加入 lint-staged 命令,这样就能在提交代码之前,对即将提交的代码进行格式化,成功之后就会提交代码。
1、同时安装husky+lint-staged依赖
npm install lint-staged husky -D
2、git初始化项目
git init
3、在package.json中配置script脚本
{
"scripts":{
...
"prepare": "husky install",
}
}
4、本地husky钩子函数安装
npm run prepare
此时本地生成了.husky目录
5、添加git hooks
pre-commit钩子:添加的是lint-staged 对git暂存区代码的格式化操作
npx husky add .husky/pre-commit "npx lint-staged"
.husky文件中会生成pre-commit目录,内容如下:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
6、在package.json中添加如下脚本命令
// 表示在执行git commit 的时候,会触发pre-commit里的npx lint-staged命令,从而触发package.json里的lint-staged的命令。从而触发npm run lint和npm run prettier-format
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"npm run lint",
"npm run prettier-format"
]
}
7、配置commit注释校验
安装依赖
npm install @commitlint/config-conventional @commitlint/cli -D
创建commit-msg钩子
npx husky add .husky/commit-msg "npx --no -- commitlint --edit ${1}"
.husky文件中会生成commit-msg目录,内容如下:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit
根目录创建commitlint.config.cjs
module.exports = { extends: ['@commitlint/config-conventional'], rules: { 'type-enum': [ 2, 'always', [ // 编译相关的修改,例如发布版本,对项目构建或者依赖的改动 'build', // 新功能(feature) 'feat', // 修复bug 'fix', // 更新某功能 'update', // 重构 'refactor', // 文档 'docs', // 构建过程或者辅助工具的变动,如增加依赖库等 'chore', // 不影响代码运行的变动 'style', // 撤销commit,回滚到上一个版本 'revert', // 性能优化 'perf', // 测试(单元,集成测试) 'test', ], ], 'type-case': [0], 'type-empty': [0], 'scope-empty': [0], 'scope-case': [0], 'subject-full-stop': [0, 'never'], 'subject-case': [0, 'never'], 'header-max-length': [0, 'always', 74], }, };
8、提交代码时,可以通过以下命令忽略掉校验
git commit -m"commit message" --no-verify
1、安装相关依赖
npm install stylelint stylelint-config-standard -D
2、根目录新建.stylelintrc.cjs
module.exports = {
extends: [
"stylelint-config-standard"
]
}
3、查看是否配置成功
npx stylelint "**/*.css"
没有报错则配置成功
4、对scss的格式化处理
安装依赖
npm install postcss-html stylelint-config-standard-scss stylelint-config-recommended-vue postcss vite-plugin-stylelint -D
修改.stylelintrc.cjs
module.exports = {
extends: [
"stylelint-config-standard-scss",
"stylelint-config-recommended-vue/scss",
]
}
package.json配置文件
{
"scripts":{
...
"lint:css": "stylelint **/*.{vue,css,sass,scss} --fix"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"npm run lint",
"npm run prettier-format"
],
"*.{vue,less,css,scss,sass}": [
"npm run lint:css"
]
}
}
新建.stylelintignore
/dist/*
/public/*
5、可以执行npm run lint:css
来完成样式校验。
报错原因: typescript 只能理解 .ts 文件,无法理解 .vue文件
解决方法:
方法一:
安装扩展Vue - Official( TypeScript Vue Plugin (Volar)【已弃用】)
方法二:
(1)修改tsconfig.json文件
"moduleResolution": "node",
(2)配置vite-env.d.ts文件
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
type IndexType = Record<symbol | string | number, unknown>
const component: DefineComponent<IndexType, IndexType, unknown>
export default component
}
报错原因: 在ts5.0以后引入了新的模块解析策略moduleResolution:bundler
,vscode的lint也内置了ts版本,出现这样的报错可能是vscode中的ts版本较低,不支持这种解析策略。moduleResolution总结
解决方法: 到tsconfig.json
文件中,添加或修改一下内容
{
"compilerOptions": {
"moduleResolution": "node"
}
}
Error [ERR_MODULE_NOT_FOUND]: Cannot find package ‘fast-glob’ imported from E:\Code\vue\vue3-ts-test\node_modules\vite-plugin-svg-icons\dist\index.mjs
报错原因: 在安装vite-plugin-svg-icons
启动项目之后会弹出找不到fast-glob
模块,这是vite-plugin-svg-icons
库存在的问题,目前还未修复,所以只能手动安装。fast-glob
是一个快速、可靠的Node.js模块,用于匹配文件和目录。
解决方法: 安装这个工具包
npm i fast-glob -D
如有误,请指正!如有更好的搭建方式,望告知!
参考文章:
基于Vue3+Vite+TS+ESLint+Prettier+Husky+lint-staged+commitlint+stylelint的项目构建
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。