前言:很多同学想尝试徒手搭建vite3+vue3项目工程,由于牵扯到的配置比较多,在搭建过程中会出现很多疑难杂症,百度上资料天花乱坠 百家争鸣,看了之后直接亚麻呆住了。
但是你放心 既然看到了这里,就是兄弟,我今天高低带领你搭建成功,所谓弱水三千只取一瓢,我这一瓢包你药到病除
代码规范 :eslint 、prettier、stylelint、husky
vite插件:不同浏览器css前缀自动补全、css模块化、组件自动引入、代码压缩
这里采用pnpm,关于pnpm优点自行了解即可
pnpm create vite
安装命令
pnpm add vue-router pinia axios path --save
pnpm add sass sass-loader @types/node -D
vite插件:
安装命令
pnpm add postcss postcss-html postcss-import postcss-scss postcss-preset-env cssnano -D
pnpm add unplugin-auto-import unplugin-vue-components rollup-plugin-visualizer vite-plugin-compression -D
安装命令
pnpm add eslint eslint-plugin-prettier eslint-plugin-vue @typescript-eslint/eslint-plugin @typescript-eslint/parser @vue/eslint-config-prettier @vue/eslint-config-typescript vue-eslint-parser @vue/eslint-config-prettier prettier -D
module.exports = {
root: true,
env: {
node: true
},
globals: {
// Ref sugar (take 2)
$: "readonly",
$$: "readonly",
$ref: "readonly",
$shallowRef: "readonly",
$computed: "readonly",
// index.d.ts
// global.d.ts
Fn: "readonly",
PromiseFn: "readonly",
RefType: "readonly",
LabelValueOptions: "readonly",
EmitType: "readonly",
TargetContext: "readonly",
ComponentElRef: "readonly",
ComponentRef: "readonly",
ElRef: "readonly",
global: "readonly",
ForDataType: "readonly",
ComponentRoutes: "readonly",
// script setup
defineProps: "readonly",
defineEmits: "readonly",
defineExpose: "readonly",
withDefaults: "readonly"
},
extends: [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"@vue/prettier",
"@vue/eslint-config-typescript"
],
parser: "vue-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: 2020,
sourceType: "module",
jsxPragma: "React",
ecmaFeatures: {
jsx: true
}
},
overrides: [
{
files: ["*.ts", "*.vue"],
rules: {
"no-undef": "off"
}
},
{
files: ["*.vue"],
parser: "vue-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
extraFileExtensions: [".vue"],
ecmaVersion: "latest",
ecmaFeatures: {
jsx: true
}
},
rules: {
"no-undef": "off"
}
}
],
rules: {
"vue/no-v-html": "off",
"vue/require-default-prop": "off",
"vue/require-explicit-emits": "off",
"vue/multi-word-component-names": "off",
"@typescript-eslint/no-explicit-any": "off", // any
"no-debugger": "off",
"@typescript-eslint/explicit-module-boundary-types": "off", // setup()
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"vue/html-self-closing": [
"error",
{
html: {
void: "always",
normal: "always",
component: "always"
},
svg: "always",
math: "always"
}
],
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_"
}
],
"no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_"
}
],
"prettier/prettier": [
"error",
{
endOfLine: "auto"
}
]
}
};
public
dist
*.d.ts
/src/assets
package.json
.eslintrc.js
.prettierrc.js
commitlint.config.js
postcss.config.js
tailwind.config.js
stylelint.config.js
module.exports = {
bracketSpacing: true,
singleQuote: false,
arrowParens: "avoid",
trailingComma: "none"
};
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "Node",
"strict": false,
"jsx": "preserve",
"importHelpers": true,
"experimentalDecorators": true,
"strictFunctionTypes": false,
"skipLibCheck": true,
"esModuleInterop": true,
"isolatedModules": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"sourceMap": true,
"baseUrl": ".",
"allowJs": false,
"resolveJsonModule": true,
"lib": ["dom", "esnext"],
"incremental": true,
"paths": {
"@/*": ["src/*"],
"@build/*": ["build/*"]
},
"types": [
"node",
"vite/client",
"element-plus/global",
// "@pureadmin/table/volar",
// "@pureadmin/descriptions/volar",
// "unplugin-vue-define-options/macros-global"
],
"typeRoots": ["./node_modules/@types/", "./types"]
},
"include": [
"mock/*.ts",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"types/*.d.ts",
"vite.config.ts"
],
"exclude": ["node_modules", "dist", "**/*.js"]
}
安装命令
pnpm add stylelint stylelint-config-prettier stylelint-config-recess-order stylelint-config-standard stylelint-order stylelint-scss --save-dev
根目录添加 .stylelint.config.js文件
module.exports = {
root: true,
plugins: ["stylelint-order"],
customSyntax: "postcss-html",
extends: ["stylelint-config-standard", "stylelint-config-prettier"],
rules: {
"selector-class-pattern": null,
"selector-pseudo-class-no-unknown": [
true,
{
ignorePseudoClasses: ["global"]
}
],
"selector-pseudo-element-no-unknown": [
true,
{
ignorePseudoElements: ["v-deep"]
}
],
"at-rule-no-unknown": [
true,
{
ignoreAtRules: [
"tailwind",
"apply",
"variants",
"responsive",
"screen",
"function",
"if",
"each",
"include",
"mixin"
]
}
],
"no-empty-source": null,
"named-grid-areas-no-invalid": null,
"unicode-bom": "never",
"no-descending-specificity": null,
"font-family-no-missing-generic-family-keyword": null,
"declaration-colon-space-after": "always-single-line",
"declaration-colon-space-before": "never",
"rule-empty-line-before": [
"always",
{
ignore: ["after-comment", "first-nested"]
}
],
"unit-no-unknown": [true, { ignoreUnits: ["rpx"] }],
"order/order": [
[
"dollar-variables",
"custom-properties",
"at-rules",
"declarations",
{
type: "at-rule",
name: "supports"
},
{
type: "at-rule",
name: "media"
},
"rules"
],
{ severity: "warning" }
]
},
ignoreFiles: ["**/*.js", "**/*.jsx", "**/*.tsx", "**/*.ts", "**/*.json"],
overrides: [
{
files: ["*.vue", "**/*.vue", "*.html", "**/*.html"],
extends: ["stylelint-config-recommended", "stylelint-config-html"],
rules: {
"keyframes-name-pattern": null,
"selector-pseudo-class-no-unknown": [
true,
{
ignorePseudoClasses: ["deep", "global"]
}
],
"selector-pseudo-element-no-unknown": [
true,
{
ignorePseudoElements: ["v-deep", "v-global", "v-slotted"]
}
]
}
}
]
};
到此,代码规范已经安装完毕,下面我们在package.json中添加一下命令
package.json 中 scripts 添加以下命令
"lint:eslint": "eslint --cache --max-warnings 0 \"{src,mock,build}/**/*.{vue,js,ts,tsx}\" --fix",
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,css,scss,postcss,less}\" --cache --cache-location node_modules/.cache/stylelint/",
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"
module.exports = {
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
"{!(package)*.json}": ["prettier --write--parser json"],
"package.json": ["prettier --write"],
"*.vue": ["eslint --fix", "prettier --write", "stylelint --fix"],
"*.{vue,css,scss,postcss,less}": ["stylelint --fix", "prettier --write"],
"*.md": ["prettier --write"]
};
执行命令
pnpm add husky lint-staged pretty-quick -D
npx husky add .husky/pre-commit //生成pre-commit 文件
"scripts":{
"lint:lint-staged": "lint-staged -c ./.husky/lintstagedrc.js",
"lint:pretty": "pretty-quick --staged",
"prepare": "husky install"
}
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
. "$(dirname "$0")/common.sh"
[ -n "$CI" ] && exit 0
pnpm run lint:lint-staged
pnpm run lint:pretty
每个小朋友的vscode设置大相径庭,这里索性一步到位设置好,照顾好每一位卡拉米
根目录创建 .vscode 文件夹,并在该目录中添加设置文件及用户片段
{
"recommendations": [
"christian-kohler.path-intellisense",
"vscode-icons-team.vscode-icons",
"davidanson.vscode-markdownlint",
"stylelint.vscode-stylelint",
"bradlc.vscode-tailwindcss",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"redhat.vscode-yaml",
"csstools.postcss",
"mikestead.dotenv",
"eamodio.gitlens",
"antfu.iconify",
"Vue.volar"
]
}
{
"editor.formatOnType": true,
"editor.formatOnSave": true,
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.tabSize": 2,
"editor.formatOnPaste": true,
"editor.guides.bracketPairs": "active",
"files.autoSave": "afterDelay",
"git.confirmSync": false,
"workbench.startupEditor": "newUntitledFile",
"editor.suggestSelection": "first",
"editor.acceptSuggestionOnCommitCharacter": false,
"css.lint.propertyIgnoredDueToDisplay": "ignore",
"editor.quickSuggestions": {
"other": true,
"comments": true,
"strings": true
},
"files.associations": {
"editor.snippetSuggestions": "top"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"iconify.excludes": ["el"]
}
{
"Vue3.0快速生成模板": {
"prefix": "Vue3.0",
"body": [
"",
"\t\n",
"\t",
"\n",
"\n",
"",
"$2"
],
"description": "Vue3.0"
}
}
{
"Vue3.2+快速生成模板": {
"prefix": "Vue3.2+",
"body": [
"\n",
"",
"\t\n",
"\t",
"\n",
"",
"$2"
],
"description": "Vue3.2+"
}
}
这里以elementPlus为例
pnpm install element-plus
这里直接推荐官网的自动导入,自动导入插件上面已经安装,vite.config配置文件在最后
import { defineConfig } from "vite";
import { resolve } from "path";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import AutoImport from "unplugin-auto-import/vite"; // ref、computed等api自动引入
import Components from "unplugin-vue-components/vite"; // 组件自动引入
import { visualizer } from "rollup-plugin-visualizer"; //资源包分析可视化
import viteCompression from "vite-plugin-compression"; //代码压缩模式
import vue from "@vitejs/plugin-vue";
//路径处理
const pathResolve = (dir: string): string => {
return resolve(__dirname, ".", dir);
};
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()], //element 组件
imports: ["vue", "vue-router"],
dts: pathResolve("types/auto-imports.d.ts")
}),
Components({
resolvers: [ElementPlusResolver()], //element 组件
extensions: ["vue"],
// 组件名称包含目录,防止同名组件冲突
directoryAsNamespace: true,
dts: pathResolve("types/components.d.ts")
}),
visualizer({
emitFile: false,
// file: "stats.html", //分析图生成的文件名
open: true //如果存在本地服务端口,将在打包后自动展示
}),
viteCompression({
deleteOriginFile: false,
algorithm: "brotliCompress" //可选 [ ‘gzip’ , ‘brotliCompress’ ,‘deflate’ , ‘deflateRaw’]
})
],
resolve: {
//路径别名
alias: {
"@": pathResolve("src"),
"@assets": pathResolve("src/assets")
}
},
server: {
// 是否开启 https
https: false,
// 端口号
port: 8080,
host: "0.0.0.0",
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {}
},
build: {
sourcemap: false,
// 消除打包大小超过500kb警告
chunkSizeWarningLimit: 4000,
rollupOptions: {
input: {
index: pathResolve("index.html")
},
// 静态资源分类打包
output: {
chunkFileNames: "static/js/[name]-[hash].js",
entryFileNames: "static/js/[name]-[hash].js",
assetFileNames: "static/[ext]/[name]-[hash].[ext]"
}
}
}
});
关于 pinia、axios、vue-router,大家可自由发挥,这里仅提供最基础的项目搭建。
项目代码仓库如下,后续会不断更新:
https://gitee.com/caoqingyu/vue3-element-admin