vue3配合vite初始化项目的一些配置
# Vue 3 + TypeScript + Vite 项目创建和配置代码风格和 eslint
# 初始化项目
pnpm create vite
# 解决找不到./App.vue
问题
在src/vite-env.d.ts
里加入以下代码
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue';
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>;
export default component;
}
2
3
4
5
6
7
8
# 配置运行自动打开浏览器
package.json
{
"scripts": {
"dev": "vite --open",
"build": "vue-tsc && vite build",
"preview": "vite preview"
}
}
2
3
4
5
6
7
# eslint 配置
安装eslint
pnpm i eslint -D
生成配置文件eslint.cjs
npx eslint --init
You can also run this command directly using 'npm init @eslint/config'.
Need to install the following packages:
@eslint/create-config
Ok to proceed? (y) y
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · vue
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JavaScript
The config that you've selected requires the following dependencies:
@typescript-eslint/eslint-plugin@latest eslint-plugin-vue@latest @typescript-eslint/parser@latest
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · pnpm
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 安装插件
p i -D eslint-plugin-import eslint-plugin-vu
e eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin
-node @babel/eslint-parser
2
3
新建eslint
忽略文件.eslintignore
dist
node_modules
2
3
运行脚本修改
{
"script": {
"lint": "eslint src",
"fix": "eslint src --fix"
}
}
2
3
4
5
6
# 配置 prettier
安装依赖包
pnpm install -D eslint-plugin-prettier prettier eslint-config-prettier
.prettierrc.json
添加规则
{
"singleQuote": true,
"semi": false,
"bracketSpacing": true,
"htmlWhitespaceSensitivity": "ignore",
"endOfLine": "auto",
"trailingComma": "all",
"tabWidth": 2
}
2
3
4
5
6
7
8
9
.prettierignore
忽略文件
/dist/*
/html/*
.local
/node_modules/**
**/*.sh
/public/*
2
3
4
5
6
7
使用命令pnpm run lint
检测,使用pnpm run fix
解决格式问题
# 配置 stylelint
css 的 lint 工具,检查 css 的语法错误和不合理的写法
pnpm add sass sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order stylelint-config-standard-scss -D
配置.stylelintrc.cjs
// @see https://stylelint.bootcss.com/
module.exports = {
extends: [
'stylelint-config-standard', // 配置stylelint拓展插件
'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
'stylelint-config-standard-scss', // 配置stylelint scss插件
'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
'stylelint-config-prettier', // 配置stylelint和prettier兼容
],
overrides: [
{
files: ['**/*.(scss|css|vue|html)'],
customSyntax: 'postcss-scss',
},
{
files: ['**/*.(html|vue)'],
customSyntax: 'postcss-html',
},
],
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml'],
/**
* null => 关闭该规则
* always => 必须
*/
rules: {
'value-keyword-case': null, // 在 css 中使用 v-bind,不报错
'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
'no-empty-source': null, // 关闭禁止空源码
'selector-class-pattern': null, // 关闭强制选择器类名的格式
'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符
'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box
'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask
'selector-pseudo-class-no-unknown': [
// 不允许未知的选择器
true,
{
ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到
},
],
},
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
.stylelintignore
忽略文件
/node_modules/*
/dist/*
/html/*
/public/*
2
3
4
5
配置脚本运行
{
"scripts": {
"lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
}
}
2
3
4
5
最后配置统一的prettier
来格式化我们的 js 和 css 以及 html 代码
{
"scripts": {
"dev": "vite --open",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"lint": "eslint src",
"fix": "eslint src --fix",
"format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"",
"lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix",
"lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix"
}
}
2
3
4
5
6
7
8
9
10
11
12
# 安装配置 husky
pnpm install husky -D
生成配置
npx husky-init
Need to install the following packages:
husky-init
Ok to proceed? (y) y
husky-init updating package.json
setting prepare script to command "husky install"
husky - Git hooks installed
husky - created .husky/pre-commit
please review changes in package.json
2
3
4
5
6
7
8
9
10
11
修改.husky/pre-commit
文件内容,在提交代码之前先格式化一下代码
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm run lint
pnpm run format
git add .
2
3
4
5
6
7
# 安装配置 cmmitlint
pnpm add @commitlint/config-conventional @commitlint/cli -D
创建配置文件commitlint.config.cjs
module.exports = {
ignores: [commit => commit.includes('init')],
extends: ['@commitlint/config-conventional'],
rules: {
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'subject-case': [0],
},
};
2
3
4
5
6
7
8
9
10
11
12
在package.json
里添加运行脚本
{
"scripts": {
"commitlint": "commitlint --config commitlint.config.cjs -e -V"
}
}
2
3
4
5
现在我们提交代码的时候必须带上以下关键字
feat 新功能
fix 修改 bug
docs 文档修改
style 代码格式修改 非 css 修改
refactor 代码重构
pref 优化相关
test 测试用例
chore 其他修改 构建流程等
revert 回滚
build 编译
2
3
4
5
6
7
8
9
10
配置husky
npx husky add .husky/commit-msg
添加以下内容
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm commitlint
2
3
4
再次提交就必须以git commit -m "feat: xxx"
的格式来提交了
# 配置强制使用pnpm
包管理工具
在根目录创建scripts/preinstall.js
文件
if (!/pnpm/.test(process.env.npm_execpath || '')) {
console.warn(`\u001b[33mThis repository must using pnpm as the package manager ` + ` for scripts to work properly.\u001b[39m\n`);
process.exit(1);
}
2
3
4
配置命令
{
"scripts": {
"preinstall": "node ./scripts/preinstall.js"
}
}
2
3
4
5
当我们使用npm
或者yarn
来安装包的时候就会报错了,install
的时候会触发preinstall
的生命周期钩子
yarn add element-plus
yarn add v1.22.10
info No lockfile found.
$ node ./scripts/preinstall.js
This repository must using pnpm as the package manager for scripts to work properly.
error Command failed with exit code 1.
2
3
4
5
6
7
# 集成 element-plus
pnpm install element-plus @element-plus/icons-vue
入口文件main.ts
安装element-plus
默认支持英语,设置为中文
import ElementPlus from 'element-plus';
import 'element-plus/dist/index.css';
import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
const app = createApp(App);
app.use(ElementPlus, {
locale: zhCn,
});
2
3
4
5
6
7
8
在vite-env.d.ts
中添加代码
declare module 'element-plus/dist/locale/zh-cn.mjs';
在tsconfig.json
中添加
{
"compilerOptions": {
"types": ["element-plus/global"]
}
}
2
3
4
5
# 配置 src 文件目录别名
在vite.config.ts
里配置
import path from 'path';
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve('./src'), // 相对路径
},
},
});
2
3
4
5
6
7
8
9
10
tsconfig.json
文件调整
{
"compilerOptions": {
"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录
"paths": {
// 路径映射,相对于 baseUrl
"@/*": ["src/*"]
}
}
}
2
3
4
5
6
7
8
9
注意 vscode 的插件vetur
对 vue3 的兼容不是很好,会对于引入的组件会爆红
# 项目环境变量的配置
- 开发环境 development
- 测试环境 testing
- 生产环境 production 一般情况下一个环境对应一台服务器 项目根目录分别添加开发、生产和测试环境的文件
.env.development
.env.production
.env.test
2
3
文件内容
# 变量必须以 VITE_ 为前缀的才能暴露给外部获取
NODE_ENV = 'development'
VITE_APP_TITLE = 'xxx 后台'
VITE_APP_BASE_API = '/dev-api'
2
3
4
# 变量必须以 VITE_ 为前缀的才能暴露给外部获取
NODE_ENV = 'production'
VITE_APP_TITLE = 'xxx 后台'
VITE_APP_BASE_API = '/dev-api'
2
3
4
# 变量必须以 VITE_ 为前缀的才能暴露给外部获取
NODE_ENV = 'test'
VITE_APP_TITLE = 'xxx 后台'
VITE_APP_BASE_API = '/dev-api'
2
3
4
配置运行的脚本命令
{
"scripts": {
"dev": "vite --open",
"build:test": "vue-tsc && vite build --mode test",
"build:pro": "vue-tsc && vite build --mode production"
}
}
2
3
4
5
6
7
通过import.meta.env
来获取环境变量
# svg 图标配置
安装 SVG 依赖插件
pnpm install vite-plugin-svg-icons -D
在vite.config.ts
里配置插件
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
export default defineConfig({
plugins: [
vue(),
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'icon-[dir]-[name]',
}),
],
resolve: {
alias: {
'@': path.resolve('./src'),
},
},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在入口文件main.ts
导入配置项
// svg 需要的配置代码
import 'virtual:svg-icons-register';
app.mount('#app');
2
3
在项目中使用,去阿里云图标库官网点击下载,复制svg
代码,然后在src/assets/icons/
新建一个对应的名称的menu.svg
文件,将复制的代码粘贴进去。
<template>
<div>
<h1>测试svg</h1>
<!-- 图标的外层容器节点 -->
<svg style="width: 30px; height: 30px">
<!-- 内部需要使用 use 标签结合使用 -->
<!-- xlink:href 执行用哪一个图标 属性值务必是以 #icon-图标名称 -->
<!-- use标签的 fill 属性可以设置图标的颜色 -->
<use xlink:href="#icon-menu" fill="red"></use>
</svg>
</div>
</template>
2
3
4
5
6
7
8
9
10
11
12
这样使用比较费劲,封装成一个全局组件
新建一个src/components/SvgIcon/index.vue
组件
<script lang="ts" setup>
// 接收父组件传递过来的参数
defineProps({
// xlink:href属性值的前缀
prefix: {
type: String,
default: '#icon-',
},
// 提供使用的图标的名字
name: String,
// 接收父组件传递的颜色
color: {
type: String,
default: '',
},
// 接收父组件传递过来的图标的宽度
width: {
type: String,
default: '16px',
},
// 接收父组件传递过来的图标的宽度
height: {
type: String,
default: '16px',
},
});
</script>
<template>
<svg :style="{ width, height }">
<!-- 内部需要使用 use 标签结合使用 -->
<!-- xlink:href 执行用哪一个图标 属性值务必是以 #icon-图标名称 -->
<!-- use标签的 fill 属性可以设置图标的颜色 -->
<use :xlink:href="prefix + name" :fill="color"></use>
</svg>
</template>
<style scoped></style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
使用
<script setup lang="ts">
import SvgIcon from '@/components/SvgIcon/index.vue';
</script>
<template>
<div>
<h1>测试svg</h1>
<svg-icon name="phone" width="100px" height="100px"></svg-icon>
</div>
</template>
<style scoped lang="scss"></style>
2
3
4
5
6
7
8
9
10
11
12
将组件定义为全局组件,不需要import
直接使用
在main.ts
中使用app.component
进行注册
import SvgIcon from '@/components/SvgIcon/index.vue';
app.component('SvgIcon', SvgIcon);
app.mount('#app');
2
3
这是比较简单的方式,但是考虑到后续可能全局组件会很多,我们需要自定义一个注册全局组件的插件
/src/components/index.ts
import SvgIcon from './SvgIcon/index.vue'
import type { App } from 'vue'
// 全局组件的对象
const allGlobalComponents = { SvgIcon }
// 对外暴露插件对象
const install = (app: App) => {
Object.entries(allGlobalComponents).forEach(([key, value]) => {
app.component(key, value)
})
}
export default install
2
3
4
5
6
7
8
9
10
11
12
13
14
在main.ts
中注册
// 引入自定义插件对象:注册整个项目全局组件
import globalComponent from '@/components';
// 注册了之后会触发插件对象的 install 方法
app.use(globalComponent);
2
3
4