项目搭建的过程
项目初始化
构建生产环境和预览环境
- 修改配置文件vite.config.ts
根据模式对环境做相关配置
1 2 3 4 5
| export default defineConfig(({ mode }) => { return { plugins: [vue()], }; });
|
- 新增环境文件.env
一份用于指定模式的文件(例如 .env.production)会比通用形式的优先级更高(例如 .env)
已经存在的环境变量有最高的优先级,不会被 .env 类文件覆盖
.env 类文件会在 Vite 启动一开始时被加载,而改动会在重启服务器后生效
- 添加Typescript提示
src目录下的 env.d.ts 文件
1 2 3 4 5 6 7 8 9 10
|
interface ImportMetaEnv { readonly VITE_APP_TITLE: string }
interface ImportMeta { readonly env: ImportMetaEnv }
|
- 环境变量配置
配置端口、mock服务开关、基础路径等等
1 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
| // .env
VITE_PORT = 3000
VITE_USE_MOCK = true VITE_MOCK_URL = http://127.0.0.1:8888/mock/8888
//.env.development NODE_ENV=development
VITE_PUBLIC_PATH = / VITE_BASE_URL = http://192.168.1.123:2323/demo/api
// .env.production NODE_ENV=production VITE_OUTPUT_DIR = dist
VITE_DROP_CONSOLE = true //删除console VITE_DROP_DEBBUGER = true //删除debug
VITE_PUBLIC_PATH = / VITE_BASE_URL = /demo/api
// .env.preview NODE_ENV=preview VITE_OUTPUT_DIR = preview
VITE_DROP_CONSOLE = false VITE_DROP_DEBBUGER = false
VITE_PUBLIC_PATH = / VITE_BASE_URL = http://192.168.1.123:2323/demo/api
|
- vite配置
安装 yarn add @types/node -D
1 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 46 47 48 49 50 51 52
| import { defineConfig, loadEnv } from 'vite'; import vue from '@vitejs/plugin-vue'; import { resolve } from 'path';
export default defineConfig(({ mode }) => { const root = process.cwd(); const env = loadEnv(mode, root);
const dropConsole: boolean = env.VITE_DROP_CONSOLE !== 'false'; const dropDebugger: boolean = env.VITE_DROP_DEBBUGER !== 'false';
return { base: env.VITE_PUBLIC_PATH, resolve: { alias: [ { find: '@/', replacement: `${resolve(root, './src')}/` } ] }, server: { host: true, port: Number(env.VITE_PORT), open: true }, build: { target: 'es2015', outDir: env.VITE_OUTPUT_DIR, minify: 'terser', terserOptions: { compress: { keep_infinity: true, drop_console: dropConsole, drop_debugger: dropDebugger } }, chunkSizeWarningLimit: 2000 }, preview: { host: true, open: true }, plugins: [ vue(), ] }; });
|
1 2 3 4 5 6 7
|
"scripts": { "dev": "vite", "build": "vue-tsc --noEmit && vite build", "preview": "npm run build && vite build --mode preview && vite preview --mode preview", },
|
1 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
| { "compilerOptions": { "target": "esnext", "useDefineForClassFields": true, "module": "esnext", "moduleResolution": "node", "strict": true, "jsx": "preserve", "sourceMap": true, "resolveJsonModule": true, "isolatedModules": true, "esModuleInterop": true, "lib": ["esnext", "dom"], "skipLibCheck": true, "baseUrl": "./", "paths": { "@/*": ["src/*"] }, "types": ["vite/client"] }, "include": [ "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", ], "exclude": ["node_modules", "dist", "preview"], "references": [{ "path": "./tsconfig.node.json" }] }
|
添加自动导入Vue Api
1 2 3
| npm i unplugin-auto-import unplugin-vue-components -D
yarn add unplugin-auto-import unplugin-vue-components -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import AutoImport from 'unplugin-auto-import/vite'; import Components from 'unplugin-vue-components/vite';
export default defineConfig({ plugins: [ vue(), AutoImport({ imports: ['vue'] }), Components({ }), ], })
|
1 2 3 4 5
|
rules: { 'no-undef': 'off' }
|
element-ui plus 自动导入参考官方文档
来源:unplugin-vue-components
接入现代CSS工程化
集成sass
1 2 3 4
| // src/assets/style/main.scss
$test-color: blue;
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| export default defineConfig(({ mode }) => { return { css: { preprocessorOptions: { scss: { additionalData: '@import "@/assets/style/main.scss";', }, }, }, plugins: [vue()], }; });
|
集成 WindiCSS
1
| yarn add windicss vite-plugin-windicss -D
|
1 2 3 4 5 6 7 8 9
| // vite.config.ts import windi from "vite-plugin-windicss";
export default defineConfig(({ mode }) => { return { plugins: [vue(), windi()], }; });
|
- 引入css
配置添加相关配置文件,查阅windicss官方文档
1 2 3
| import 'virtual:windi.css'; import 'virtual:windi-devtools';
|
1 2 3
| class="bg-red-200 p-2 border-10 border-yellow-500 text-blue-600 hover:bg-purple-400"
|
约束代码风格
Eslint
选中相应的配置进行安装
eslint-plugin-vue
规范等级:
base 基础
essential 预设
strongly-recommended 推荐
recommended 最严谨
vue3:
Vue 3.x 需要加上 vue3 前綴,’plugin:vue/vue3-essential’
Airbnb:
Airbnb JavaScript编码规范指南(ES6)中文版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| module.exports = { env: { browser: true, es2021: true, node: true, }, extends: [ 'plugin:vue/essential', 'airbnb-base', ], parserOptions: { ecmaVersion: 'latest', parser: '@typescript-eslint/parser', sourceType: 'module', }, plugins: [ 'vue', '@typescript-eslint', ], rules: { }, };
|
安装yarn add eslint-define-config -D
修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import defineConfig from "eslint-define-config";
module.exports = defineConfig({ env: { browser: true, es2021: true, node: true, }, extends: ["plugin:vue/essential", "airbnb-base"], parserOptions: { ecmaVersion: "latest", parser: "@typescript-eslint/parser", sourceType: "module", }, plugins: ["vue", "@typescript-eslint"], rules: {}, });
|
新增 ESLint 規則,避免 Vite2 环境下错误提示和额外的一些配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| rules: { quotes: ['error', 'single'], semi: ['error', 'always'],
'import/no-unresolved': 'off', 'import/no-extraneous-dependencies': 'off', 'import/extensions': 'off', 'global-require': 'off', 'no-plusplus': 'off', 'no-undef': 'off', 'vue/multi-word-component-names': 'off' }
|
创建 .eslintignore
来配置eslint
需要忽略哪些文件或者文件夹
1 2 3
| node_modules dist preview
|
Prettier
- 配置
项目根目录创建 .prettierrc.js
1 2 3 4 5 6 7 8 9
| module.exports = { printWidth: 80, tabWidth: 2, useTabs: false, singleQuote: true, semi: true, trailingComma: 'none', bracketSpacing: true };
|
配置项
创建 .prettierignore
来配置prettire
忽略文件或者文件夹
1 2 3
| node_modules dist preview
|
集成Prettier到ESLint工具中
1
| yarn add eslint-config-prettier eslint-plugin-prettier -D
|
eslint-config-prettier用来覆盖 ESLint 本身的规则配置,而eslint-plugin-prettier则是用于让 Prettier 来接管eslint –fix即修复代码的能力
1 2 3 4 5 6 7 8 9 10 11 12 13
|
parser: 'vue-eslint-parser' , extends: [ 'plugin:@typescript-eslint/recommended', 'prettier', 'plugin:prettier/recommended', ], rules: { 'prettier/prettier': 'error', }
|
- 解决vue3
defineProps' is not defined
问题
1 2 3 4 5 6 7 8
|
globals: { defineProps: 'readonly', defineEmits: 'readonly', defineExpose: 'readonly', withDefaults: 'readonly' },
|
1 2 3 4
| "scripts": { "lint:script": "eslint --ext .js,.jsx,.ts,.tsx,.vue --fix ./", },
|
- 安装插件
在VSCode中安装ESLint
和Prettier
这两个插件,并且在设置区中开启Format On Save
,保存自动格式化。
Stylelint
1
| yarn add stylelint stylelint-prettier stylelint-config-prettier stylelint-config-recess-order stylelint-config-standard stylelint-config-standard-scss -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| module.exports = { plugins: ['stylelint-scss', 'stylelint-prettier'], extends: [ 'stylelint-config-standard', 'stylelint-config-standard-scss', 'stylelint-config-recess-order', 'stylelint-config-prettier', 'stylelint-prettier/recommended' ], rules: { 'prettier/prettier': true, 'at-rule-no-unknown': null, 'scss/at-rule-no-unknown': true } };
|
1 2 3 4
| "scripts": { "lint:style": "stylelint --fix \"src/**/*.{css,scss}\"" },
|
其他集成
路由
- 新建路由文件src/router/index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [ { path: '/', name: 'Home', component: () => import('@/views/Home.vue'), meta: { requiresAuth: true } }, ];
const router = createRouter({ history: createWebHashHistory(), routes, });
export default router;
|
1 2 3 4 5 6 7 8 9 10
| import 'vue-router';
declare module 'vue-router' { interface RouteMeta { isAdmin?: boolean; requiresAuth: boolean; } }
|
官网:Vue Router
Pinia 状态管理
1 2 3
| yarn add pinia
npm install pinia
|
1 2 3 4
| import { createPinia } from 'pinia'
app.use(createPinia())
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| import { defineStore } from 'pinia';
const useUserStore = defineStore('user', { state: () => { return { count: 0 }; }, actions: { increment() { this.count++; } } });
export default { useUserStore };
|
Animate.css
1 2 3 4 5 6 7 8
| <transition name="animate" enter-active-class="animate__zoomIn" leave-active-class="animate__zoomOut" class="animate__animated" > <div></div> </transition>
|
时间日期格式话工具moment.js
见其他短文
Axios + VueRequest
见其他短文
UI库 Element Plus
官网:Element Plus
参考来源:
详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程
Vite2 + Vue3 + TypeScript + Pinia 搭建一套企业级的开发脚手架
vue3中加入eslint和prettier
Vite2 + Vue 3 + TypeScript + WindiCSS