ToB企服应用市场:ToB评测及商务社交产业平台

标题: 手把手完成前端Vue3 + Vite项目工程化搭建 [打印本页]

作者: 水军大提督    时间: 2024-11-26 11:20
标题: 手把手完成前端Vue3 + Vite项目工程化搭建
vue3_vite_project

基于 Vue3 + Vite 搭建的前端工程化项目演示模板
环境准备


技能栈

技能栈描述Vue渐进式 JavaScript 框架Vite新一代前端开发与构建工具Element Plus基于 Vue 3,面向设计师和开发者的组件库Pinia符合直觉的 Vue.js 状态管理库vue-routerVue.js 的官方路由管理库SassCSS 预处置惩罚器VueUse基于 Vue 组合式 API 的实用工具集Axios用于浏览器和 Node.js 的基于 Promise 的 HTTP 请求库Echarts一个基于 JavaScript 的开源可视化图表库Eslint可配置的 JavaScript 检查器Prettier代码格式化工具 项目构建

  1. #创建项目
  2. npm create vite
  3. #安装依赖
  4. npm install
  5. #启动项目
  6. npm run dev
  7. #构建项目
  8. npm run build
复制代码
到这一步,假如能乐成运行项目,恭喜你!一个项目的基本框架已经搭建完成!
整理项目布局

主要是让项目工程更加感觉清晰
  1. <!--src/App.vue-->
  2. <template>
  3.   <div>
  4.     <h1>App</h1>
  5.   </div>
  6. </template>
复制代码
删除 src/style.css 文件
删除 src/main.js 中引入的 style.css 文件
使用 Git 管理源代码

  1. #Git仓库初始化
  2. git init
  3. #添加所有文件到版本库
  4. git add .
  5. #提交所有文件到版本库
  6. git commit -m "feat: 项目初始化完成"
  7. #新建 dev 分支,并切换到 dev 分支
  8. git checkout -b dev
复制代码
本地代码堆栈初始化完成,之后的开发工作都在当 dev 分支上举行
根据技能栈提供的文档,完成项目搭建

安装 Element Plus 组件库

  1. #安装 Element Plus
  2. npm install element-plus
复制代码
引入 Element Plus 组件库并使用测试安装效果
  1. # src/main.js
  2. import { createApp } from 'vue'
  3. import ElementPlus from 'element-plus' # 新增
  4. import 'element-plus/dist/index.css' # 新增
  5. import App from './App.vue'
  6. const app = createApp(App)
  7. app.use(ElementPlus) # 新增:使用 Element Plus 组件库
  8. app.mount('#app')
复制代码
测试安装效果
  1. <!--src/App.vue-->
  2. <template>
  3.   <div>
  4.     <h1>App</h1>
  5.     <el-button type="primary">button</el-button>
  6.   </div>
  7. </template>
复制代码
当按钮能正常显示时,说明安装乐成
安装 Vue Router 路由管理库

  1. #安装 Vue Router
  2. npm install vue-router
复制代码
在项目的 src 目次下新建一个 views 目次,然后在 views 目次下新建两个页面,用于路由跳转。
在项目的 src 目次下新建一个 router 目次,然后在 router 目次下新建一个 index.js 文件,该文件会作为 Vue Router 的入口文件,该文件内容如下
  1. // src/router/index.js
  2. import {createRouter, createWebHistory} from "vue-router";
  3. const router = new createRouter({
  4.     history: createWebHistory(),
  5.     routes: [
  6.         {
  7.             path: "/login",
  8.             name: "Login",
  9.             component: () => import("../views/login/index.vue"),
  10.         },
  11.         {
  12.             path: "/dashboard",
  13.             name: "Dashboard",
  14.             component: () => import("../views/dashboard/index.vue"),
  15.         },
  16.     ]
  17. })
  18. export default router
复制代码
在 src/main.js 文件中引入 Vue Router,并使用 Vue Router
  1. // src/main.js
  2. // ...
  3. import router from './router' // 新增
  4. app.use(router) // 新增:使用 Vue Router
  5. // ...
复制代码
修改 App.vue 文件,添加路由跳转
  1. <template>
  2.   <div class="app-container">
  3.     <ul>
  4.       <li><router-link to="/dashboard">首页</router-link></li>
  5.       <li><router-link to="/login">登录</router-link></li>
  6.     </ul>
  7.     <router-view />
  8.   </div>
  9. </template>
复制代码
访问首页和登录页,查看路由是否正常跳转
router-link 和 router-view 是 Vue Router 的两个核心组件,router-link 是用来实现路由跳转,router-view 是用来显示路由对应的内容。
安装 Pinia 状态管理库

  1. #安装 Pinia
  2. npm install pinia
复制代码
在项目的 src 目次下新建一个 store 目次,然后在 store 目次下新建一个 index.js 文件,该文件会作为 Pinia 的入口文件
  1. // src/store/index.js
  2. import {createPinia} from 'pinia'
  3. const pinia = createPinia()
  4. export default pinia
复制代码
在 src/main.js 文件中引入 Pinia,并使用 Pinia
  1. // src/main.js
  2. // ...
  3. import pinia from './store' // 新增
  4. app.use(router) // 新增:使用 Pinia
  5. // ...
复制代码
在 src/store 目次下创建一个 modules 目次,然后在 modules 目次下创建一个 user 状态管理对象,用于管理整个项目的用户登录状态
  1. // src/store/modules/user.js
  2. import {defineStore} from 'pinia'
  3. import {ref} from 'vue'
  4. const useUserStore = defineStore('user', () => {
  5.     const userInfo = ref({})
  6.     const loginStatus = ref(false)
  7.     const token = ref('')
  8.     /**
  9.      * 登录
  10.      */
  11.     function handleLogin() {
  12.         return new Promise((resolve, reject) => {
  13.             if(Math.random() > 0.8){
  14.                 loginStatus.value = true
  15.                 token.value = String(new Date().getTime())
  16.                 userInfo.value = {
  17.                     name: 'admin',
  18.                     avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif?imageView2/1/w/80/h/80',
  19.                 }
  20.                 resolve('登录成功')
  21.             }else {
  22.                 reject('登录失败')
  23.             }
  24.         })
  25.     }
  26.     /**
  27.      * 退出登录
  28.      */
  29.     function handleLogout() {
  30.         return new Promise((resolve) => {
  31.             loginStatus.value = false
  32.             token.value = ''
  33.             userInfo.value = {}
  34.             resolve()
  35.         })
  36.     }
  37.     return {
  38.         userInfo,
  39.         loginStatus,
  40.         token,
  41.         handleLogin,
  42.         handleLogout
  43.     }
  44. })
  45. export default useUserStore
复制代码
在登录页面,使用 Pinia 获取用户状态管理对象,并调用登录方法
  1. <!--src/views/login/index.vue-->
  2. <script setup>
  3. import useUserStore from '../../store/modules/user'
  4. const userStore = useUserStore()
  5. import {ElMessage } from 'element-plus'
  6. /**
  7. * 登录
  8. */
  9. function login() {
  10.   userStore.handleLogin().then((res) => {
  11.     ElMessage.success(res)
  12.   }).catch(err => {
  13.     ElMessage.error(err)
  14.   })
  15. }
  16. /**
  17. * 退出登录
  18. */
  19. function loginOut() {
  20.   userStore.handleLogout().then(() => {
  21.     ElMessage.success('退出登录成功')
  22.   }).catch(err => {
  23.     ElMessage.error(err)
  24.   })
  25. }
  26. </script>
  27. <template>
  28. <div class="login-container">
  29.   <el-button type="primary" @click="login">登 录</el-button>
  30.   <el-button type="primary" @click="loginOut">退出登录</el-button>
  31.   <hr>
  32.   <h1>当前登录状态:{{ userStore.loginStatus ? '已登录' : '未登录' }}</h1>
  33.   <ul>
  34.     <li>用户名:{{ userStore.userInfo.name }}</li>
  35.     <li>头 像:<img :src="userStore.userInfo.avatar" alt=""></li>
  36.   </ul>
  37. </div>
  38. </template>
复制代码
安装 Sass CSS 预处置惩罚器

  1. #安装 Sass,安装时需要添加 -D 参数,表示将 Sass 添加到开发依赖中,在打包过程中,Sass 会自动编译为 CSS
  2. npm install sass -D
复制代码
在项目的 src 目次下新建一个 styles 目次,然后在 styles 目次下新建一个 variables.scss 文件,该文件存放全局的 Sass 变量
  1. //src/styles/variables.scss
  2. $success: #48C78E;
  3. $danger: #F28482;
复制代码
在首页测试 Sass 变量,在 src/views/dashboard/index.vue 文件中修改如下
  1. <template>
  2.   <h1 class="success">这是一个成功样式</h1>
  3.   <h2 class="danger">这是一个告警样式</h2>
  4. </template>
  5. <style scoped lang="scss">
  6. .success{
  7.   color:$success;
  8. }
  9. .danger{
  10.   color: $danger;
  11. }
  12. </style>
复制代码
此时浏览器会提示 Undefined variable. ,由于我们必要在 vite.config.js 文件中引入该文件,才能使用 Sass 变量
  1. // vite.config.js
  2. import { defineConfig } from 'vite'
  3. import vue from '@vitejs/plugin-vue'
  4. export default defineConfig({
  5.     plugins: [vue()],
  6.     css: {
  7.         // CSS 预处理器
  8.         preprocessorOptions: {
  9.             // 定义全局 SCSS 变量
  10.             scss: {
  11.                 javascriptEnabled: true,
  12.                 additionalData: "@use '/src/styles/variables.scss' as *;",
  13.             },
  14.         },
  15.     },
  16. })
复制代码
查看页面会显示乐成和告警样式,表示 Sass 变量已经正常工作了
安装 VueUse 工具库

  1. #安装 VueUse
  2. npm i @vueuse/core
复制代码
在 src/views/dashboard/index.vue 文件中,使用 VueUse 的 useMouse 方法,获取当前鼠标实时位置
  1. <script setup>
  2. import {useMouse} from '@vueuse/core'
  3. const {x,y} = useMouse()
  4. </script>
  5. <template>
  6.   <h1 class="success">这是一个成功样式</h1>
  7.   <h2 class="danger">这是一个告警样式</h2>
  8.   <p>当前鼠标位置:X:{{ x }}、Y:{{ y }}</p>
  9. </template>
  10. <style scoped lang="scss">
  11. .success{
  12.   color:$success;
  13. }
  14. .danger{
  15.   color: $danger;
  16. }
  17. </style>
复制代码
页面上会实时显示鼠标的位置,表示 VueUse 工具库已经正常工作了,必要使用其它函数,可以参考 VueUse 文档
安装 Axios 网络请求库

  1. #安装 Axios
  2. npm install axios
复制代码
在 src 目次下新建一个 utils 目次,然后在 utils 目次下新建一个 request.js 文件,在该文件中,可以在发起请求前向请求头中添加一些请求头等信息
  1. // src/utils/request.js
  2. import axios from  'axios'
  3. const request = axios.create({
  4.     baseURL: 'http://xxx.xxx.xxx.xxx // 请求的后端接口地址
  5. })
  6. /**
  7. * 请求拦截器
  8. */
  9. request.interceptors.request.use(config => {
  10.     console.log('请求参数:',config)
  11. })
  12. /**
  13. * 响应拦截器
  14. */
  15. request.interceptors.response.use(response => {
  16.     console.log('响应参数:',response)
  17. })
  18. export default request
复制代码
在 src 目次下新建一个 api 目次,然后在 api 目次下新建一个 user.js 文件,在该文件中,封装一些用户相干的接口
  1. import request from "../utils/request";
  2. /**
  3. * 获取验证码
  4. * @param checkKey
  5. */
  6. export function getCodeInfo(checkKey) {
  7.     return request({
  8.         method: "get",
  9.         url: `/xxx/xxx/${checkKey}`,
  10.     });
  11. }
复制代码
回到登录页面,测试获取验证码接口,修改如下:
  1. <script setup>
  2. import {getCodeInfo} from '../../api/user'
  3. import {onMounted, ref} from "vue";
  4. const captchaInfo = ref('')
  5. onMounted(() => {
  6.   getCodeInfo(new Date().getTime()).then(({data}) => {
  7.     captchaInfo.value = data.result
  8.   })
  9. })
  10. </script>
  11. <template>
  12. <div class="login-container">
  13.   <ul>
  14.     <li>验证码:<img :src="captchaInfo" alt=""></li>
  15.   </ul>
  16. </div>
  17. </template>
复制代码
页面上乐成显示了验证码,表示 Axios 工具库已经正常工作了,之后其它 API 接口都统一放到 src/api 目次下统一管理
安装 Echarts 图表库

  1. #安装 Echarts
  2. npm install echarts
复制代码
在 src/views/dashboard/index.vue 文件中,使用 Echarts 的 init 方法,初始化一个图表
  1. <script setup>
  2. import * as echarts from 'echarts';
  3. import {onMounted, ref} from "vue";
  4. const chartRef = ref(null)
  5. let echartClient = null
  6. onMounted(() => {
  7.   initChart()
  8. })
  9. function initChart() {
  10.   echartClient =  echarts.init(chartRef.value)
  11.   echartClient.setOption({
  12.     tooltip: {},
  13.     xAxis: {
  14.       data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
  15.     },
  16.     yAxis: {},
  17.     series: [
  18.       {
  19.         name: '销量',
  20.         type: 'bar',
  21.         data: [5, 20, 36, 10, 10, 20]
  22.       }
  23.     ]
  24.   })
  25. }
  26. </script>
  27. <template>
  28.   <div class="chart-box" ref="chartRef" ></div>
  29. </template>
  30. <style scoped lang="scss">
  31. .chart-box{
  32.   width: 600px;
  33.   height: 400px;
  34. }
  35. </style>
复制代码
页面上可以看到一个柱状图,表示 Echarts 工具库已经正常工作了
安装 Eslint 代码检查工具

  1. #安装 Eslint 及相关插件
  2. npm install eslint -D
  3. npm install eslint-config-airbnb-base -D
  4. npm install eslint-define-config -D
  5. npm install eslint-plugin-import -D
  6. npm install eslint-plugin-vue -D
复制代码
在项目更目次下新建一个 .eslintrc.js 文件,配置如下:
  1. // .eslintrc.js
  2. const { defineConfig } = require("eslint-define-config");
  3. module.exports = defineConfig({
  4.   root: true,
  5.   env: {
  6.     browser: true,
  7.     node: true,
  8.     jest: true,
  9.     es6: true,
  10.   },
  11.   plugins: ["vue"],
  12.   parser: "vue-eslint-parser",
  13.   parserOptions: {
  14.     ecmaVersion: "latest",
  15.     sourceType: "module",
  16.     allowImportExportEverywhere: true,
  17.     ecmaFeatures: {
  18.       jsx: true,
  19.     },
  20.   },
  21.   extends: [
  22.     "eslint-config-airbnb-base",
  23.     "eslint:recommended",
  24.     "plugin:vue/vue3-essential",
  25.     "plugin:vue/vue3-recommended",
  26.     "plugin:vue/vue3-strongly-recommended",
  27.     "plugin:import/recommended",
  28.     "plugin:import/errors",
  29.     "plugin:import/warnings",
  30.     // ".eslintrc-auto-import.json", // 解决 Eslint 提示 no-undef 错误
  31.     "prettier",
  32.     "plugin:prettier/recommended",
  33.   ],
  34.   /**
  35.    * 规则说明:off 或 0 - 关闭规则;warn 或 1 - 打开规则作为警告(不影响退出代码);error 或 2 - 打开规则作为错误(退出代码将为 1)
  36.    */
  37.   rules: {
  38.     // 不使用制表符
  39.     "prettier/prettier": 2,
  40.     // 强制使用分号
  41.     semi: [2, "always"],
  42.     // 强制使用双引号
  43.     quotes: [2, "double"],
  44.     // 解决最后一个逗号
  45.     // "comma-dangle": [2, "never"],
  46.     // 关闭默认参数应为最后一个
  47.     "default-param-last": 0,
  48.     // 禁止未使用的变量
  49.     "no-unused-vars": 1,
  50.     // 关闭组件命名规则
  51.     "vue/multi-word-component-names": 0,
  52.     // 禁止使用多余的包
  53.     "import/no-extraneous-dependencies": 0,
  54.     // 确保在导入路径内一致使用文件扩展名
  55.     "import/extensions": 0,
  56.     // 确保导入指向可以解析的文件/模块
  57.     "import/no-unresolved": 0,
  58.     // 首选默认导出导入/首选默认导出
  59.     "import/prefer-default-export": 0,
  60.     // 要求使用 let 或 const 而不是 var
  61.     "no-var": 2,
  62.     // 禁止使用 new 以避免产生副作用
  63.     "no-new": 1,
  64.     // 禁止变量声明与外层作用域的变量同名
  65.     "no-shadow": 0,
  66.     // 禁用 console
  67.     "no-console": 0,
  68.     // 禁止标识符中有悬空下划线
  69.     "no-underscore-dangle": 0,
  70.     // 禁止在可能与比较操作符相混淆的地方使用箭头函数
  71.     "no-confusing-arrow": 0,
  72.     // 禁用一元操作符 ++ 和 --
  73.     "no-plusplus": 0,
  74.     // 禁止对 function 的参数进行重新赋值
  75.     "no-param-reassign": 0,
  76.     // 禁用特定的语法
  77.     "no-restricted-syntax": 0,
  78.     // 禁止在变量定义之前使用它们
  79.     "no-use-before-define": 0,
  80.     // 禁止直接调用 Object.prototypes 的内置属性
  81.     "no-prototype-builtins": 0,
  82.     // 禁止可以在有更简单的可替代的表达式时使用三元操作符
  83.     "no-unneeded-ternary": 2,
  84.     // 禁止重复模块导入
  85.     "no-duplicate-imports": 2,
  86.     // 禁止在对象中使用不必要的计算属性
  87.     "no-useless-computed-key": 2,
  88.     // 禁止不必要的转义字符
  89.     "no-useless-escape": 0,
  90.     // 禁用 continue 语句
  91.     "no-continue": 0,
  92.     // 强制使用一致的缩进
  93.     indent: [2, 2, { SwitchCase: 1 }],
  94.     // 强制使用骆驼拼写法命名约定
  95.     camelcase: 0,
  96.     // 强制类方法使用 this
  97.     "class-methods-use-this": 0,
  98.     // 要求构造函数首字母大写
  99.     "new-cap": 2,
  100.     // 强制一致地使用 function 声明或表达式
  101.     "func-style": 0,
  102.     // 强制一行的最大长度
  103.     "max-len": 0,
  104.     // 要求 return 语句要么总是指定返回的值,要么不指定
  105.     "consistent-return": 0,
  106.     // 强制switch要有default分支
  107.     "default-case": 2,
  108.     // 强制剩余和扩展运算符及其表达式之间有空格
  109.     "rest-spread-spacing": 2,
  110.     // 要求使用 const 声明那些声明后不再被修改的变量
  111.     "prefer-const": 2,
  112.     // 强制箭头函数的箭头前后使用一致的空格
  113.     "arrow-spacing": 2,
  114.     // 只强制对象解构,不强制数组解构
  115.     "prefer-destructuring": [2, { object: true, array: false }],
  116.     // 禁止在对象中使用不必要的计算属性
  117.     "no-unused-expressions": 0,
  118.   },
  119. });
复制代码
修改 package.json 文件,在 scripts 中添加 "lint": "eslint --ext .js,.vue --fix src" ,运行 npm run lint 命令,会自动修复全部代码标题
安装 Prettier 代码格式化工具

  1. #安装 Prettier 及相关插件
  2. npm install -D prettier
  3. npm install -D eslint-plugin-prettier
复制代码
在项目根目次下新建一个 .prettierrc.cjs 文件,配置如下:
  1. module.exports = {
  2.   // JSX 中的右尖括号是否换行,默认false
  3.   jsxBracketSameLine: false,
  4.   // 文件末尾是否换行,默认true
  5.   endOfLine: "auto",
  6.   // 换行符类型 (lf|crlf|cr;默认lf)
  7.   rangeStart: 0,
  8.   // 单个属性是否换行,默认false
  9.   singleAttributePerLine: false,
  10.   // 是否使用双引号,默认true
  11.   doubleQuote: true,
  12.   // 是否使用单行注释,默认false
  13.   experimentalTernaries: false,
  14.   // (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always)
  15.   arrowParens: "always",
  16.   // 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false
  17.   bracketSameLine: false,
  18.   // 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar})
  19.   bracketSpacing: true,
  20.   // 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto)
  21.   embeddedLanguageFormatting: "auto",
  22.   // 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css)
  23.   htmlWhitespaceSensitivity: "css",
  24.   // 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false
  25.   insertPragma: false,
  26.   // 在 JSX 中使用单引号替代双引号,默认false
  27.   jsxSingleQuote: false,
  28.   // 每行最多字符数量,超出换行(默认80)
  29.   printWidth: 120,
  30.   // 超出打印宽度 (always | never | preserve )
  31.   proseWrap: "preserve",
  32.   // 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;)
  33.   quoteProps: "as-needed",
  34.   // 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false
  35.   requirePragma: false,
  36.   // 结尾添加分号
  37.   semi: true,
  38.   // 使用单引号 (true:单引号;false:双引号)
  39.   singleQuote: false,
  40.   // 缩进空格数,默认2个空格
  41.   tabWidth: 2,
  42.   // 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号
  43.   trailingComma: "es5",
  44.   // 指定缩进方式,空格或tab,默认false,即使用空格
  45.   useTabs: false,
  46.   // vue 文件中是否缩进 <style> 和 <script> 标签,默认 false
  47.   vueIndentScriptAndStyle: false,
  48. };
复制代码
修改 package.json 文件,在 scripts 中添加 "prettier": "prettier --write src/**/*.{vue,js,jsx,ts,tsx,json,css,scss,md}" ,运行 npm run prettier 命令,会自动格式化全部代码
性能优化及打包计谋

配置 Element Plus 按需导入

  1. #安装插件
  2. npm install -D unplugin-vue-components unplugin-auto-import
复制代码
修改 vite.config.js 文件,添加了 vue, vue-router, @vueuse/core 相干函数自动导入配置
自动导入 src/**/components 目次下的组件,无需在页面中手动导入组件,添加了路径别名,@ 默认指向 src 目次,导入模块的时候可以直接使用 import xxx from "@/xxx/xxx" 形式
  1. // vite.config.js
  2. import { defineConfig } from "vite";
  3. import vue from "@vitejs/plugin-vue";
  4. import AutoImport from "unplugin-auto-import/vite";
  5. import Components from "unplugin-vue-components/vite";
  6. import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
  7. import { resolve } from "path";
  8. const pathSrc = resolve(__dirname, "src");
  9. export default defineConfig({
  10.   plugins: [
  11.     vue(),
  12.     // 自动导入
  13.     AutoImport({
  14.       // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
  15.       imports: ["vue", "vue-router", "@vueuse/core"],
  16.       resolvers: [
  17.         // 自动导入 Element Plus 相关函数
  18.         ElementPlusResolver(),
  19.       ],
  20.       eslintrc: {
  21.         enabled: true, // 解决 Eslint 提示 no-undef 错误
  22.       },
  23.       // 配置文件位置 (false:关闭自动生成)
  24.       dts: resolve(__dirname, "src/types/auto-imports.d.ts"),
  25.     }),
  26.     Components({
  27.       resolvers: [
  28.         // 自动导入 Element Plus 组件
  29.         ElementPlusResolver(),
  30.       ],
  31.       // 指定自定义组件位置(默认:src/components)
  32.       dirs: ["src/**/components"],
  33.       // 配置文件位置 (false:关闭自动生成)
  34.       dts: resolve(__dirname, "src/types/components.d.ts"),
  35.     }),
  36.   ],
  37.   resolve: {
  38.     // 导入文件时省略文件扩展名
  39.     extensions: [".js", ".ts", ".vue", ".json", "es"],
  40.     // 配置路径别名
  41.     alias: { "@": pathSrc },
  42.   },
  43.   // ...
  44. });
复制代码
删除 src/main.js 文件中之前引入的 Element Plus 的代码
  1. // src/main.js
  2. import { createApp } from "vue";
  3. // import ElementPlus from "element-plus";  // 删除
  4. import router from "./router";
  5. import pinia from "./store";
  6. // import "element-plus/dist/index.css";  // 删除
  7. import App from "./App.vue";
  8. const app = createApp(App);
  9. app.use(router);
  10. app.use(pinia);
  11. // app.use(ElementPlus); // 删除
  12. app.mount("#app");
复制代码
删除 src/views/login/index.vue 中的 import { ElMessage } from "element-plus"; 代码,现在全部与 Element Plus 相干的代码都被自动导入了,无需再手动引入。
修改 .eslintrc.cjs 文件中 extends 项,添加 ".eslintrc-auto-import.json" 配置,办理 Eslint 提示 no-undef 错误
  1. # ...
  2. extends: [
  3. # ...
  4.   ".eslintrc-auto-import.json", # 解决 Eslint 提示 no-undef 错误
  5. ]
  6. # ...
复制代码
按需导入 Echarts 图表库

在 src/utils 文件夹下创建 echarts.js 文件,把必要用到的图表组件导入到该文件中,在必要使用 Echarts 的地方直接导入该文件,这样就可以按需导入 Echarts 图表库了
  1. // src/utils/echarts.js
  2. // 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
  3. import * as echarts from "echarts/core";
  4. // 引入柱状图图表,图表后缀都为 Chart
  5. import { BarChart } from "echarts/charts";
  6. // 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
  7. import {
  8.   TitleComponent,
  9.   TooltipComponent,
  10.   GridComponent,
  11.   DatasetComponent,
  12.   TransformComponent,
  13. } from "echarts/components";
  14. // 标签自动布局、全局过渡动画等特性
  15. import { LabelLayout, UniversalTransition } from "echarts/features";
  16. // 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
  17. import { CanvasRenderer } from "echarts/renderers";
  18. // 注册必须的组件
  19. echarts.use([
  20.   TitleComponent,
  21.   TooltipComponent,
  22.   GridComponent,
  23.   DatasetComponent,
  24.   TransformComponent,
  25.   BarChart,
  26.   LabelLayout,
  27.   UniversalTransition,
  28.   CanvasRenderer,
  29. ]);
  30. export default echarts;
复制代码
修改 src/views/dashboard/index.vue 文件,引入 src/utils/echarts.js 文件,这样就可以按需导入 Echarts 图表库了
  1. // import * as echarts from "echarts"; // 删除
  2. import echarts from "@/utils/echarts"; // 新增
  3. // ...
复制代码
打包静态资源优化

  1. #安装插件
  2. npm install terser -D
复制代码
修改 vite.config.js 文件,添加了 terser 配置,打包时会自动压缩 js 文件,配置了 build.rollupOptions 将打包后的静态资源按文件范例举行分类
  1. import { defineConfig } from "vite";
  2. // ...
  3. export default defineConfig({
  4. // ...
  5.   // 预览模式配置
  6.   preview: {
  7.     port: 8081,
  8.     open: true,
  9.   },
  10.   // 开发模式配置
  11.   server: {
  12.     https: false, // 是否开启 https
  13.     port: 8080, // 端口号
  14.     host: "0.0.0.0", // 监听所有地址
  15.     open: true, // 服务启动时是否自动打开浏览器
  16.     cors: true, // 允许跨域
  17.     proxy: {}, // 自定义代理规则
  18.   },
  19.   // 构建配置
  20.   build: {
  21.     chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告
  22.     minify: "terser", // Vite 2.6.x 以上需要配置 minify: "terser", terserOptions 才能生效
  23.     terserOptions: {
  24.       compress: {
  25.         keep_infinity: true, // 防止 Infinity 被压缩成 1/0,这可能会导致 Chrome 上的性能问题
  26.         drop_console: true, // 生产环境去除 console
  27.         drop_debugger: true, // 生产环境去除 debugger
  28.       },
  29.       format: {
  30.         comments: false, // 删除注释
  31.       },
  32.     },
  33.     rollupOptions: {
  34.       output: {
  35.         // 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
  36.         entryFileNames: "js/[name].[hash].js",
  37.         // 用于命名代码拆分时创建的共享块的输出命名
  38.         chunkFileNames: "js/[name].[hash].js",
  39.         // 用于输出静态资源的命名,[ext]表示文件扩展名
  40.         assetFileNames: (assetInfo) => {
  41.           const info = assetInfo.name.split(".");
  42.           let extType = info[info.length - 1];
  43.           // console.log('文件信息', assetInfo.name)
  44.           if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {
  45.             extType = "media";
  46.           } else if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(assetInfo.name)) {
  47.             extType = "img";
  48.           } else if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {
  49.             extType = "fonts";
  50.           }
  51.           return `${extType}/[name].[hash].[ext]`;
  52.         },
  53.       },
  54.     },
  55.   },
  56. });
复制代码
开启 Gzip 压缩

  1. #安装插件
  2. npm install vite-plugin-compression -D
复制代码
修改 vite.config.js 文件,添加了 vite-plugin-compression 插件
  1. import { defineConfig } from "vite";
  2. // ...
  3. import viteCompression from "vite-plugin-compression";
  4. export default defineConfig({
  5.   plugins: [
  6.     // ...
  7.     viteCompression(),
  8.   ],
  9. // ...
  10. });
复制代码
在 Vite 构建项目时开启 Gzip 压缩后,为了确保 Nginx 能够精确处置惩罚并返回 Gzip 压缩后的文件,你必要在 Nginx 服务器上举行相应的配置
  1. http {
  2.     gzip on;
  3.     gzip_static on; # 开启静态gzip功能,优先返回预压缩的.gz文件
  4.     server {
  5.         listen 8080;
  6.         server_name localhost;
  7.         location / {
  8.               root /usr/share/nginx/html/dist; # 替换为你的实际项目部署目录
  9.               index  index.html index.htm;
  10.               try_files $uri $uri/ /index.html;
  11.               # 指定如果存在预压缩文件,则优先返回 .gz 文件
  12.               gzip_static always;
  13.         }
  14.         error_page   500 502 503 504  /50x.html;
  15.         location = /50x.html {
  16.             root   html;
  17.         }
  18.     }
  19. }
复制代码
在这个配置中,Nginx会在接收到请求时首先查找是否存在对应的.gz预压缩文件,假如存在则直接返回该文件,否则会返回原始未压缩的文件。
确保Vite构建时生成的预压缩文件与原始文件位于同一目次下,并且命名规范遵循Nginx的预期(即与原始文件同名,但扩展名为.gz)。同时,在重启Nginx服务后使新配置生效。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4