本篇推荐且默认你使用的是VSCode编辑器。
配置 VSCode #
让你的同事至少在这个项目内可以使用跟你一样的设置。
在根目录下添加 .vscode
文件夹,用于配置该项目使用的 VSCode 设置。
- 添加
[extensions.json](https://code.visualstudio.com/docs/editor/extension-marketplace#_workspace-recommended-extensions)
,用于推荐 VSCode 插件:
{
"recommendations": [
// Vue3 必备
"johnsoncodehk.volar", // volar - 官方的 Vue3 扩展,需要禁用 Vetur!
"johnsoncodehk.vscode-typescript-vue-plugin", // TypeScript Vue Plugin - 用于支持在 TS 中 import *.vue 文件。
"dbaeumer.vscode-eslint", // ESLint 支持
"esbenp.prettier-vscode", // Prettier 格式化
// 其他推荐插件
"voorjaar.windicss-intellisense",
"ecmel.vscode-html-css",
"abusaidm.html-snippets",
"xabikos.JavaScriptSnippets",
"mikestead.dotenv",
"yzhang.markdown-all-in-one",
"formulahendry.auto-rename-tag",
"coenraads.bracket-pair-colorizer-2",
"vscode-icons-team.vscode-icons",
"zhuangtongfa.Material-theme",
"eamodio.gitlens",
"donjayamanne.githistory"
]
}
- 添加
[settings.json](https://code.visualstudio.com/docs/getstarted/settings)
,用于配置 VSCode 设置: ```json { // 为指定的语法定义配置文件或使用带有特定规则的配置文件。 “emmet.syntaxProfiles”: { “javascript”: “jsx”, “vue”: “html”, “vue-html”: “html” }, // 使用空格代替tab缩进,2格缩进 “editor.tabSize”: 2, “editor.insertSpaces”: true, // volar配置 “volar.autoCompleteRefs”: true, “volar.formatting.printWidth”: 100, // 各文件格式化配置 “[vue]”: { “editor.defaultFormatter”: “johnsoncodehk.volar” }, “[jsonc]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[javascript]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[html]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[json]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[javascriptreact]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[less]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[scss]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[css]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” }, “[typescript]”: { “editor.defaultFormatter”: “esbenp.prettier-vscode” } }
<a name="yPMMs"></a>
# 配置 tsconfig.json [#](https://staging-cn.vuejs.org/guide/typescript/overview.html#configuring-tsconfigjson)
> 先将 Vite 模板预设的`tsconfig.node.json`删除。
> 对于我们准备搭建的中小型且无需单元测试的项目来说,tsconfig配置无需做太多的项目分割。
<a name="maNY9"></a>
## 声明文件管理
在**根目录**下新建一个`typings`文件夹,将预设模板中的`src/env.d.ts`文件放到`typings`文件夹中。<br />未来单独的ts声明,也都放在这个文件夹中进行统一管理。
<a name="ACqpQ"></a>
## 修改 tsconfig.json
修改`tsconfig.json`内容,详细说明都在注释中:
```json
{
// 编译选项配置参考:
// TypeScript 官方英文: https://www.typescriptlang.org/tsconfig#compilerOptions
// TypeScript 官方中文: https://www.tslang.cn/docs/handbook/compiler-options.html
"compilerOptions": {
// 解析路径及路径别名
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
// 影响 Vite 编译选项,都选用最新的
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
// `"noImplicitThis": true` 是 `strict` 的一部分
// 在这里再次添加,以防止一些用户决定禁用 `strict`
"noImplicitThis": true,
"strict": true,
// Vite 推荐/要求
// See <https://cn.vitejs.dev/guide/features.html#typescript-compiler-options>
// See <https://cn.vitejs.dev/guide/features.html#usedefineforclassfields>
// See <https://cn.vitejs.dev/guide/features.html#json>
"isolatedModules": true,
"useDefineForClassFields": true,
"resolveJsonModule": true,
// Vue 推荐/要求
"jsx": "preserve", // Vue 支持 Jsx 需要
"preserveValueImports": true, // 支持 `<script setup>`
"importsNotUsedAsValues": "error", // 导入类型时,强制使用 `import type` 而不是 `import`
// Recommended
"esModuleInterop": true, // 兼容 esm 与 cjs
"allowJs": true, // 允许 js、ts 混用
"forceConsistentCasingInFileNames": true, // 大小写敏感
"skipLibCheck": true, // See <https://github.com/vuejs/vue-cli/pull/5688>
"experimentalDecorators": true, // 支持 ES 装饰器
// 仅该路径下的 d.ts 会被全局包含
"typeRoots": ["./node_modules/@types/", "./typings"]
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"typings/**/*.d.ts",
"vite.config.ts"
],
"exclude": ["node_modules/*"]
}
配置 Vite #
这里主要讲几个常用的 Vite 配置项,更多配置可点击 # 号查看官方文档。
Vite 的配置文件就在根目录的 vite.config.ts
中。
路径别名配置 - resolve.alias #
首先运行pnpm add -D @types/node
命令安装 node 模块的ts类型声明。
避免使用node模块时,提示 找不到模块“path”或其相应的类型声明
的报错。
在vite.config.ts
中使用path
模块搭配设置路径别名:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
const pathResolve = (dir: string): string => {
return resolve(__dirname, '.', dir)
}
/**
* vite 配置
* @see https://cn.vitejs.dev/config/
*/
export default defineConfig({
base: './',
resolve: {
alias: {
'@': pathResolve('./src'),
'~': pathResolve('./src/assets'),
'#': pathResolve('./src/scripts')
}
},
plugins: [vue()]
})
同时设置tsconfig.json
的compilerOptions.paths
字段,这样 VSCode 编辑器才能识别路径:
{
"compilerOptions": {
// 设置解析非相对模块名称的基本目录
"baseUrl": ".",
// 设置模块名到基于baseUrl的路径映射,可以设置路径别名的语法提示
"paths": {
"@/*": ["src/*"],
"~/*": ["src/assets/*"],
"#/*": ["src/scripts/*"]
},
},
}
CSS 配置 - CSS Module、预处理器 #
预处理器 Less #
由于本文会使用ant-design-vue
,因此预处理器选择使用less
。
Vite对预处理器提供了内置的支持。因此安装预处理器依赖即可,无需额外配置:
# 安装 less 预处理器
pnpm add -D less
若要在 Vite 中使用 Less 全局变量:
在
src/assets/style
文件夹下创建common.less
文件@primary-color: #3554f5; // 全局主色
在
vite.config.ts
中注入全局变量声明:
export default defineConfig({
css: {
preprocessorOptions: {
less: {
// 全局 less变量 & less mixins
modifyVars: {
hack: `true; @import (reference) "${pathResolve('./src/assets/style/common.less')}";`
},
// ant-design-vue 自动按需引入兼容
javascriptEnabled: true
}
}
},
})
- 使用 Less 全局变量:
<style lang="less" module>
.xxx {
color: @primary-color;
}
</style>
CSS Modules #
使用 标签,css会被编译为 CSS Modules 。并且将生成的 CSS 类作为$style
对象的键暴露给组件。
先设置 vite.config.ts
:
export default defineConfig({
css: {
/**
* css modules 设置
* @see https://cn.vitejs.dev/guide/features.html#css-modules
*/
modules: {
localsConvention: 'camelCase'
}
},
})
在.vue
文件中使用:
<!-- 1: 使用css module,同时使用less -->
<template>
<div :class="$style['test']"></div>
</template>
<style lang="less" module>
.test {}
</style>
<!-- 2: 给 css module 添加别名 'css' -->
<template>
<div :class="css['test']"></div>
</template>
<style lang="less" module="css">
.test {}
</style>
<!-- 3: 想修改子组件样式如ant-design-vue组件的样式,可以使用 :global() -->
<style lang="less" module>
.container {
width: 100%;
:global(.ant-menu) {
height: 64px;
:global(.ant-menu-item)::after {
bottom: 1px;
}
}
}
</style>
环境变量与模式(env)配置 #
本篇假设你需要三个环境:本地开发环境、预发布环境、正式环境 点击 # 查看官方文档有详细的解释,这里仅提炼重点和实操
创建环境变量
我们先在根目录创建三个.env
文件:
# 有三个环境的情况下,我们至少需要3个env文件
.env # 公共配置(同时用作正式环境配置)
.env.development # 本地开发环境配置
.env.staging # 预发布环境配置
三个env
文件的内容:
# .env 公共 & 正式环境
NODE_ENV=production
VITE_ENV=production
VITE_TITLE='Vue3 TypeScript 项目'
VITE_BASE_URL='https://www.google.com'
# .env.development 本地开发环境
NODE_ENV=development
VITE_ENV=development
VITE_BASE_URL='http://www.sogou.com'
# .env.staging 预发布环境变量
NODE_ENV=production
VITE_ENV=staging
VITE_BASE_URL='https://www.baidu.com'
这里有两个需要注意的点:
- 预发布、正式等打包时的环境变量,
NODE_ENV
都必须设置为production
。 - 只有以
VITE_
为前缀的变量才会暴露给经过 Vite 处理的代码。修改打包命令
在创建好环境变量后,我们需要修改package.json
的打包命令,让程序知道使用什么环境:
使用{ "scripts": { "dev": "vite", "build": "vue-tsc --noEmit --skipLibCheck && vite build", "build:staging": "vue-tsc --noEmit --skipLibCheck && vite build --mode staging" }, }
--mode
来告诉vite build
使用什么模式的env配置,默认为production
模式。TypeScript 支持 #
之前在根目录下已经创建好的typings
文件夹中,创建一个名为env.d.ts
的文件:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_ENV: 'development' | 'staging' | 'production'
readonly VITE_TITLE: string
readonly VITE_BASE_URL: string
// 更多环境变量...
}
interface ImportMeta {
readonly env: ImportMetaEnv
}
访问env变量
console.log(import.meta.env.VITE_ENV)
console.log(import.meta.env.VITE_TITLE)
配置 ESLint + Prettier
安装依赖
pnpm add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-prettier eslint-define-config eslint-plugin-vue vite-plugin-eslint vue-eslint-parser prettier -D
ESLint 配置
在根目录下添加 .eslintrc.js
、.eslintignore
文件:
// @ts-check
const { defineConfig } = require('eslint-define-config')
module.exports = defineConfig({
root: true,
env: {
browser: true,
node: true,
es6: true
},
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
jsxPragma: 'React',
ecmaFeatures: {
jsx: true
}
},
extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
rules: {
// 未使用的变量,允许添加 '_' 前缀来表示不使用
'no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_'
}
],
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_'
}
],
// 可以允许出现 any 类型
'@typescript-eslint/no-explicit-any': 'off',
// 允许使用 require
'@typescript-eslint/no-var-requires': 'off',
// 允许使用 v-html 指令
'vue/no-v-html': ['off'],
// 不限制vue属性顺序
'vue/attributes-order': 'off',
// Vue3 允许多个根节点
'vue/no-multiple-template-root': ['off'],
/**
* html标签自闭和规则
* @see https://eslint.vuejs.org/rules/html-self-closing.html
*/
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'never',
component: 'always'
},
svg: 'always',
math: 'always'
}
]
}
})
node_modules
dist
/public
/docs
/bin
.vscode
.idea
.husky
.local
*.sh
*.md
*.woff
*.ttf
Dockerfile
在 vite.config.ts
中添加 vite-plugin-eslint
插件:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import viteEslint from 'vite-plugin-eslint'
export default defineConfig({
plugins: [
vue(),
/**
* eslint Vite 运行、打包时校验工具
* @see https://github.com/gxmari007/vite-plugin-eslint
*/
viteEslint({
cache: false
})
]
})
Prettier 配置
在根目录下添加 .prettierrc.js
、.prettierignore
文件:
/**
* @file prettier 配置文件
*/
module.exports = {
tabWidth: 2, // 缩进字节数
useTabs: false, // 缩进不使用tab,使用空格
printWidth: 100, // 超过最大值换行
semi: false, // 在每个语句的末尾添加分号
singleQuote: true, // 使用单引号而不是双引号
trailingComma: 'es5', // 多行时尽可能打印尾随逗号<none|es5|all>
bracketSpacing: true, // 对象文字中打印括号之间的空格
endOfLine: 'auto', // 对象文字中打印括号之间的空格
arrowParens: 'avoid', // 在单个箭头函数参数周围加上括号<avoid|always>
jsxBracketSameLine: true,
htmlWhitespaceSensitivity: 'css', // 指定HTML文件的全局空格敏感度 <css|strict|ignore>
vueIndentScriptAndStyle: true,
quoteProps: 'as-needed',
jsxSingleQuote: false,
insertPragma: false,
requirePragma: false,
proseWrap: 'never',
rangeStart: 0,
}
/dist/*
/node_modules/**
.local
.output.js
**/*.svg
**/*.sh
添加 package.json
命令
{
"scripts": {
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock}/**/*.{vue,ts,tsx}\" --fix",
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\""
},
}