Vue3+Vite+Ts 项目搭建
这次的项目搭建将会在项目中集成一下功能:
- eslint 代码规范
- alias 开发路径别名
- unplugin-auto-import 按需导入 API
- unplugin-vue-components 自动导入组件
- unocss 样式库
- 代码 commit 规范
- unplugin-vue-macros
相较于之前的 simple-vite-template-v2 项目模板,本次的项目搭建移除了以下功能:
- markdown 转换为 vue 组件的功能
- @unocss/preset-icons 使用
如果需要使用以上功能,可以参考 simple-vite-template-v2。
项目初始化
# 创建项目
pnpm create vite vite-vue3-ts-template --template vue-ts
# 进入项目
cd vite-vue3-ts-template
配置 pnmp
创建 .npmrc
touch .npmrc
pnpm 可以从 .npmrc 获取配置
shamefully-hoist=true
strict-peer-dependencies=false
shell-emulator=true
fetch-retries=5
fetch-retry-mintimeout=200000
fetch-retry-maxtimeout=1200000
fetch-timeout=1800000
registry=https://registry.npm.taobao.org
很多时候网络原因包下载不下来,这里的 fetch-retries、fetch-retry-maxtimeout、fetch-timeout、registry 可以根据自己的网络情况决定是否配置。
# 安装依赖
pnpm install
# 启动项目
pnpm run dev
配置 eslint
安装依赖
pnpm add -D eslint @antfu/eslint-config
配置 eslint
在项目下创建 .eslintrc
文件
touch .eslintrc
.eslintrc
内容如下
{
"extends": "@antfu"
}
在 package.json
加入如下 script
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}
配置 vscode
安装 eslint 扩展
添加如下配置到项目根目录下的 .vscode/settings.json
文件
{
"prettier.enable": false,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.organizeImports": false
},
// The following is optional.
// It's better to put under project setting `.vscode/settings.json`
// to avoid conflicts with working with different eslint configs
// that does not support all formats.
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml"
]
}
配置 alias
在 vite.config.ts
中配置 alias,添加如下代码
import path from 'node:path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
})
配置如上代码后会发现找不到模块“node:path”或其相应的类型声明和找不到名称“__dirname”。这是因为 vite 是基于 esm 的,所以需要安装 @types/node
,添加如下代码
pnpm add -D @types/node
然后关闭页面重写打开,就可以正常了。(如果还是不行,可以尝试重启编辑器)
配置 unplugin-auto-import
详细配置请参考 unplugin-auto-import
unplugin-auto-import 可以为 vite 按需导入 API,一般情况下代码如下:
import { computed, ref } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
使用 unplugin-auto-import 后,可以这样写:
const count = ref(0)
const doubled = computed(() => count.value * 2)
安装依赖
pnpm add -D unplugin-auto-import
在 vite.config.ts
中配置 unplugin-auto-import,添加如下代码
import path from 'node:path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [
vue(),
// https://github.com/unplugin/unplugin-auto-import
AutoImport({
imports: [
// 预设
'vue',
// 'vue-router',
// 'vuex',
// 自定义
{
'@vueuse/core': [
'useMouse', // import { useMouse } from '@vueuse/core',
// alias
['useFetch', 'useMyFetch'], // import { useFetch as useMyFetch } from '@vueuse/core',
],
},
],
dts: 'types/auto-imports.d.ts',
// 自动导入目录下的模块导出
// 默认情况下,它只会扫描目录下的一个级别的模块
dirs: [
// './hooks',
// './composables' // 只有根模块
// './composables/**', // 所有嵌套模块
// ...
],
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
})
这是你如果在 vue 文件中测试如下代码
<script setup lang="ts">
const msg = ref(666)
</script>
<template>
{{ msg }}
</template>
你会发现报了找不到名称“ref”的错误,这时候需要在 tsconfig.json
加入如下代码
{
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*.d.ts"]
}
这时候你会发现报了找不到名称“ref”的错误没有了~
配置 unplugin-vue-components
详细配置请参考 unplugin-vue-components
安装依赖
pnpm add -D unplugin-vue-components
在 vite.config.ts
中配置 unplugin-vue-components,添加如下代码
import path from 'node:path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [
vue(),
// https://github.com/unplugin/unplugin-auto-import
AutoImport({
imports: [
// 预设
'vue',
// 'vue-router',
// 'vuex',
// 自定义
{
'@vueuse/core': [
'useMouse', // import { useMouse } from '@vueuse/core',
// alias
['useFetch', 'useMyFetch'], // import { useFetch as useMyFetch } from '@vueuse/core',
],
},
],
dts: 'types/auto-imports.d.ts',
// 自动导入目录下的模块导出
// 默认情况下,它只会扫描目录下的一个级别的模块
dirs: [
// './hooks',
// './composables' // 只有根模块
// './composables/**', // 所有嵌套模块
// ...
],
}),
// https://github.com/unplugin/unplugin-vue-components
Components({
// 允许自动导入
include: [/\.vue$/, /\.vue\?vue/],
dts: 'types/components.d.ts',
}),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
})
这时候如果删除 App.vue 中引入的组件,会发现在未引入组件的情况下,组件也可以正常使用,这是因为 unplugin-vue-components 会自动导入组件
<script setup lang="ts">
import HelloWorld from './components/HelloWorld.vue'
</script>
规范化项目 commit
初始化 git
git init
安装相关依赖
pnpm install @commitlint/cli @commitlint/config-conventional cz-git czg husky lint-staged @esbuild-kit/cjs-loader -D
在项目根目录创建 commitlint.config.cjs
和 commitlint.config.ts
commitlint.config.cjs 内容如下:
module.exports = require('./commitlint.config.ts').default
commitlint.config.ts 内容如下:
import { execSync } from 'node:child_process'
const scopes = [
'views',
'components',
'router',
'store',
'utils',
'styles',
'assets',
'types',
'other',
]
const gitStatus = execSync('git status --porcelain || true')
.toString()
.trim()
.split('\n')
const scopeComplete = gitStatus
.find(r => ~r.indexOf('M src'))
?.replace(/(\/)/g, '%%')
?.match(/src%%((\w|-)*)/)?.[1];
const subjectComplete = gitStatus
.find(r => ~r.indexOf('M src'))
?.replace(/\//g, '%%')
?.match(/src%%((\w|-)*)/)?.[1];
export default {
rules: {
/**
* type[scope]: [function] description
* ^^^^^
*/
'scope-enum': [2, 'always', scopes],
/**
* type[scope]: [function] description
*
* ^^^^^^^^^^^^^^ empty line.
* - Something here
*/
'body-leading-blank': [1, 'always'],
/**
* type[scope]: [function] description
*
* - something here
*
* ^^^^^^^^^^^^^^
*/
'footer-leading-blank': [1, 'always'],
/**
* type[scope]: [function] description [No more than 72 characters]
* ^^^^^
*/
'header-max-length': [2, 'always', 72],
'scope-case': [2, 'always', 'lower-case'],
'subject-case': [
1,
'never',
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
],
'subject-empty': [2, 'never'],
'subject-full-stop': [2, 'never', '.'],
'type-case': [2, 'always', 'lower-case'],
'type-empty': [2, 'never'],
/**
* type[scope]: [function] description
* ^^^^
*/
'type-enum': [
2,
'always',
[
'build',
'chore',
'ci',
'docs',
'feat',
'fix',
'perf',
'refactor',
'revert',
'release',
'style',
'test',
'improvement',
],
],
},
prompt: {
defaultScope: scopeComplete,
customScopesAlign: !scopeComplete ? 'top' : 'bottom',
defaultSubject: subjectComplete && `[${subjectComplete}] `,
allowCustomIssuePrefixs: false,
allowEmptyIssuePrefixs: false,
},
}
修改 package.json
{
"scripts": {
"cz": "czg",
},
"config": {
"commitizen": {
"path": "./node_modules/cz-git"
}
},
"lint-staged": {
"*.{vue,js,ts,jsx,tsx,md,json}": "eslint --fix"
}
}
配置 husky
执行 init
npx husky-init
添加 hooks
npx husky add .husky/commit-msg 'pnpm exec commitlint --config commitlint.config.cjs --edit "${1}"'
这时候会发现项目根目录下创建了 .husky 文件夹,.husky 结构如下:
📦.husky
┣ 📂_
┃ ┣ 📜.gitignore
┃ ┗ 📜husky.sh
┣ 📜commit-msg
┗ 📜pre-commit
commit-msg 内容修改如下:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
pnpm exec commitlint --config commitlint.config.cjs --edit "${1}"
pre-commit 内容修改如下:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
pnpm exec lint-staged
配置 unocss
安装依赖
pnpm add -D unocss
配置 vite.config.ts
// vite.config.ts
import UnoCSS from 'unocss/vite'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
UnoCSS(),
],
})
配置 uno.config.ts
import {
defineConfig,
presetAttributify,
presetIcons,
presetTypography,
presetUno,
presetWebFonts,
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
export default defineConfig({
shortcuts: [
],
presets: [
presetUno(),
presetAttributify(),
presetIcons({
scale: 1.2,
warn: true,
}),
presetTypography(),
presetWebFonts({
fonts: {
sans: 'DM Sans',
serif: 'DM Serif Display',
mono: 'DM Mono',
},
}),
],
transformers: [
transformerDirectives(),
transformerVariantGroup(),
],
safelist: 'prose prose-sm m-auto text-left'.split(' '),
})
引入样式
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import '@unocss/reset/tailwind.css'
import 'uno.css'
createApp(App).mount('#app')
配置 eslint
安装 @unocss/eslint-config
这里配置的 eslint 是为了代码顺序更加美观,如果不需要可以不配置
pnpm add -D @unocss/eslint-config
在 .eslintrc
中加入:
{
"extends": [
"@antfu",
"@unocss"
],
"rules": {
"@unocss/order": "error",
"@unocss/order-attributify": "error"
}
}
安装 unocss 扩展
注意
这时候如果在代码中写样式没有提示的话,请把 .vscode/settings.json
中的 editor.quickSuggestions
设置下
{
"editor.quickSuggestions": {
"strings": "on"
}
}
上面配置好后,如果写 unocss 的样式 vscode 还是没有提示的话,请重启编辑器!!!
配置 unplugin-vue-macros
安装依赖
pnpm add -D unplugin-vue-macros
配置 vite.config.ts
import path from 'node:path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import VueMacros from 'unplugin-vue-macros/vite'
import UnoCSS from 'unocss/vite'
// https://vitejs.dev/config/
export default defineConfig({
base: './',
plugins: [
// vue(),
VueMacros({
plugins: {
vue: vue(),
},
}),
// https://github.com/unplugin/unplugin-auto-import
AutoImport({
imports: [
// 预设
'vue',
// 'vue-router',
// 'vuex',
// 自定义
{
'@vueuse/core': [
'useMouse', // import { useMouse } from '@vueuse/core',
// alias
['useFetch', 'useMyFetch'], // import { useFetch as useMyFetch } from '@vueuse/core',
],
},
],
dts: 'types/auto-imports.d.ts',
// 自动导入目录下的模块导出
// 默认情况下,它只会扫描目录下的一个级别的模块
dirs: [
// './hooks',
// './composables' // 只有根模块
// './composables/**', // 所有嵌套模块
// ...
],
}),
// https://github.com/unplugin/unplugin-vue-components
Components({
// 允许自动导入
include: [/\.vue$/, /\.vue\?vue/],
dts: 'types/components.d.ts',
}),
UnoCSS(),
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
})
添加 ts 支持
tsconfig.json
中加入如下配置:
// tsconfig.json
{
"compilerOptions": {
// ...
"types": ["unplugin-vue-macros/macros-global" /* ... */]
}
}
添加 Volar 支持
pnpm add -D @vue-macros/volar
tsconfig.json
中加入如下配置:
// tsconfig.json
{
"vueCompilerOptions": {
"plugins": [
"@vue-macros/volar/define-options",
"@vue-macros/volar/define-models",
"@vue-macros/volar/define-props",
"@vue-macros/volar/define-props-refs",
"@vue-macros/volar/short-vmodel",
"@vue-macros/volar/define-slots",
"@vue-macros/volar/jsx-directive"
]
}
}
修改 .vscode/extensions.json
{
"recommendations": [
"Vue.volar",
"Vue.vscode-typescript-vue-plugin",
"antfu.iconify",
"antfu.unocss",
"antfu.vite",
"antfu.goto-alias",
"csstools.postcss",
"dbaeumer.vscode-eslint",
"streetsidesoftware.code-spell-checker"
]
}
修改后 vscode 会自动安装这些插件,如果不需要可以删除。
总结
至此,一个基于 Vue3+Vite+Ts 的项目搭建完成!
项目集成了以下功能:
- eslint 代码规范
- alias 开发路径别名
- unplugin-auto-import 按需导入 API
- unplugin-vue-components 自动导入组件
- unocss 样式库
- 代码 commit 规范