Vite5 基础篇

Vite 是一个前端构建工具,他与Webpack最大时的区别就是开发时的工作方式,webpack是先把整个项目分析一遍,打包成bundle,再起服务,项目一大,启动和热更新就慢

Vite在开发阶段直接基于浏览器原生的ES Module,把打包这件事往后拖,浏览器用到哪个模块,服务端才即时处理哪个模块,所以启动非常快

优势主要提现在:

项目越大,开发阶段的速度优势越明显,配置层面比Webpack简单,很多常见能力是内置的

对Vue3,React,ts的支持非常自然,不需要太多额外配置

缺点: 天然依赖ESM,对老旧浏览器支持不太友好,还有一些高度定制的老Webpack项目,迁移成本会比较高

一. 开发服务器选项(开发环境)

1.port 端口号

2.open : 自动打开浏览器

3.host: 是否允许局域网访问

4.strictPort: 端口被占用是否报错

5.proxy : 代理

export default defineConfig({

server: {

port: 3000, //端口号

open: true, //自动打开浏览器

host: true, //是否允许局域网访问

strictPort: true, //端口被占用是否报错

//代理

proxy: {

'/api': {

target: 'http://localhost:8080',

changeOrigin: true

}

}

}

})

二. 生产的构建配置 build

1.outDir 打包输出目录,默认dist

2. assetsDir 静态资源放的子目录,默认assets

3. 打包后chunk 体积警告阈值,单位是KB

4. reportCompressedSize: false 是否统计gzip/brotli的体积

5. minify: 是否压缩代码,

6. rellupOptions Vite生产构建底层就是Rollup,这里是直接控制Rollup行为

optput配置

入口文件输出规则:

name: 入口名(如index)

hash: 内容hash

输出到js/目录

build: {

chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告

reportCompressedSize: false,

minify: isProduction ? "esbuild" : false, // 只在生产环境启用压缩

rollupOptions: {

output: {

// manualChunks: {

// "vue-i18n": "vue-i18n",

// },

// 用于从入口点创建的块的打包输出格式name表示文件名,hash表示该文件内容hash值

entryFileNames: "js/name.hash.js",

// 用于命名代码拆分时创建的共享块的输出命名

chunkFileNames: "js/name.hash.js",

// 用于输出静态资源的命名,ext表示文件扩展名

assetFileNames: (assetInfo: any) => {

const info = assetInfo.name.split(".");

let extType = infoinfo.length - 1;

// console.log('文件信息', assetInfo.name)

if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {

extType = "media";

} else if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(assetInfo.name)) {

extType = "img";

} else if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {

extType = "fonts";

}

return `${extType}/name.hash.ext`;

},

},

},

},

三.共享选项

1. resolve 别名配置

resolve: {

alias: {

"@": pathSrc,

},

},

2. css.preprocessorOptions 全局默认引入变量css

resolve: {

alias: {

"@": pathSrc,

},

},

css: {

preprocessorOptions: {

scss: { additionalData: `@use "@/styles/variables.scss" as *;` }

}

}

作用: 给每一个css文件自动注入这一行,相当于全局默认引入变量文件


build: {

chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告

reportCompressedSize: false,

minify: isProduction ? "esbuild" : false, // 只在生产环境启用压缩

rollupOptions: {

output: {

// manualChunks: {

// "vue-i18n": "vue-i18n",

// },

// 用于从入口点创建的块的打包输出格式name表示文件名,hash表示该文件内容hash值

entryFileNames: "js/name.hash.js",

// 用于命名代码拆分时创建的共享块的输出命名

chunkFileNames: "js/name.hash.js",

// 用于输出静态资源的命名,ext表示文件扩展名

assetFileNames: (assetInfo: any) => {

const info = assetInfo.name.split(".");

let extType = infoinfo.length - 1;

// console.log('文件信息', assetInfo.name)

if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {

extType = "media";

} else if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(assetInfo.name)) {

extType = "img";

} else if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {

extType = "fonts";

}

return `${extType}/name.hash.ext`;

},

},

},

},

3.插件 plugins

  1. plugin-vue 解析.vue文件

  2. AutoImport 自动导入: 导入ref,reactive,toRef等

  • resolves 第三方ui库
  • eslintrc 解决ESlint 报未定义变量的问题
  • vueTemplate 让template 里也支持自动导入,否则只在script生效
  • dts 是否生成类型声明文件
  1. 组件自动导入
  • resolves 让ElementPlus 组件自动按需引入
  • dts : false
  • dirs: 指定自定义组件位置,默认src/components

4. optimizeDeps 预加载项目必须的组件

5.esbuild: 用来在生产环境打包时把代码里的console和debugger删掉的

6. define 编译器全局常量替换

javascript 复制代码
import vue from "@vitejs/plugin-vue";
import { type ConfigEnv, type UserConfig, loadEnv, defineConfig, PluginOption } from "vite";

import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";

import { mockDevServerPlugin } from "vite-plugin-mock-dev-server";

import UnoCSS from "unocss/vite";
import { resolve } from "path";
import { name, version, engines, dependencies, devDependencies } from "./package.json";

// 平台的名称、版本、运行所需的 node 版本、依赖、构建时间的类型提示
const __APP_INFO__ = {
  pkg: { name, version, engines, dependencies, devDependencies },
  buildTimestamp: Date.now(),
};

const pathSrc = resolve(__dirname, "src");

// Vite配置  https://cn.vitejs.dev/config
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, process.cwd());
  const isProduction = mode === "production";
  return {
    resolve: {
      alias: {
        "@": pathSrc,
      },
    },
    css: {
      preprocessorOptions: {
        // 定义全局 SCSS 变量
        scss: {
          additionalData: `@use "@/styles/variables.scss" as *;`,
        },
      },
    },
    server: {
      host: "0.0.0.0",
      port: +env.VITE_APP_PORT,
      open: true,
      proxy: {
        // 代理 /dev-api 的请求
        [env.VITE_APP_BASE_API]: {
          changeOrigin: true,
          // 代理目标地址:https://api.youlai.tech
          target: env.VITE_APP_API_URL,
          rewrite: (path: string) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""),
        },
      },
    },
    plugins: [
      vue(),
      ...(env.VITE_MOCK_DEV_SERVER === "true" ? [mockDevServerPlugin()] : []),
      UnoCSS(),
      // API 自动导入
      AutoImport({
        // 导入 Vue 函数,如:ref, reactive, toRef 等
        imports: ["vue", "@vueuse/core", "pinia", "vue-router", "vue-i18n"],
        resolvers: [
          // 导入 Element Plus函数,如:ElMessage, ElMessageBox 等
          ElementPlusResolver({ importStyle: "sass" }),
        ],
        eslintrc: {
          enabled: false,
          filepath: "./.eslintrc-auto-import.json",
          globalsPropValue: true,
        },
        vueTemplate: true,
        // 导入函数类型声明文件路径 (false:关闭自动生成)
        dts: false,
        // dts: "src/types/auto-imports.d.ts",
      }),
      // 组件自动导入
      Components({
        resolvers: [
          // 导入 Element Plus 组件
          ElementPlusResolver({ importStyle: "sass" }),
        ],
        // 指定自定义组件位置(默认:src/components)
        dirs: ["src/components", "src/**/components"],
        // 导入组件类型声明文件路径 (false:关闭自动生成)
        dts: false,
        //dts: "src/types/components.d.ts",
      }),
    ] as PluginOption[],
    // 预加载项目必需的组件
    optimizeDeps: {
      include: [
        "vue",
        "vue-router",
        "element-plus",
        "pinia",
        "axios",
        "@vueuse/core",
        "codemirror-editor-vue3",
        "default-passive-events",
        "exceljs",
        "path-to-regexp",
        "echarts/core",
        "echarts/renderers",
        "echarts/charts",
        "echarts/components",
        "vue-i18n",
        "nprogress",
        "sortablejs",
        "qs",
        "path-browserify",
        "@stomp/stompjs",
        "@element-plus/icons-vue",
        "element-plus/es",
        "element-plus/es/locale/lang/en",
        "element-plus/es/locale/lang/zh-cn",
        "element-plus/es/components/alert/style/index",
        "element-plus/es/components/avatar/style/index",
        "element-plus/es/components/backtop/style/index",
        "element-plus/es/components/badge/style/index",
        "element-plus/es/components/base/style/index",
        "element-plus/es/components/breadcrumb-item/style/index",
        "element-plus/es/components/breadcrumb/style/index",
        "element-plus/es/components/button/style/index",
        "element-plus/es/components/card/style/index",
        "element-plus/es/components/cascader/style/index",
        "element-plus/es/components/checkbox-group/style/index",
        "element-plus/es/components/checkbox/style/index",
        "element-plus/es/components/col/style/index",
        "element-plus/es/components/color-picker/style/index",
        "element-plus/es/components/config-provider/style/index",
        "element-plus/es/components/date-picker/style/index",
        "element-plus/es/components/descriptions-item/style/index",
        "element-plus/es/components/descriptions/style/index",
        "element-plus/es/components/dialog/style/index",
        "element-plus/es/components/divider/style/index",
        "element-plus/es/components/drawer/style/index",
        "element-plus/es/components/dropdown-item/style/index",
        "element-plus/es/components/dropdown-menu/style/index",
        "element-plus/es/components/dropdown/style/index",
        "element-plus/es/components/empty/style/index",
        "element-plus/es/components/form-item/style/index",
        "element-plus/es/components/form/style/index",
        "element-plus/es/components/icon/style/index",
        "element-plus/es/components/image-viewer/style/index",
        "element-plus/es/components/image/style/index",
        "element-plus/es/components/input-number/style/index",
        "element-plus/es/components/input-tag/style/index",
        "element-plus/es/components/input/style/index",
        "element-plus/es/components/link/style/index",
        "element-plus/es/components/loading/style/index",
        "element-plus/es/components/menu-item/style/index",
        "element-plus/es/components/menu/style/index",
        "element-plus/es/components/message-box/style/index",
        "element-plus/es/components/message/style/index",
        "element-plus/es/components/notification/style/index",
        "element-plus/es/components/option/style/index",
        "element-plus/es/components/pagination/style/index",
        "element-plus/es/components/popover/style/index",
        "element-plus/es/components/progress/style/index",
        "element-plus/es/components/radio-button/style/index",
        "element-plus/es/components/radio-group/style/index",
        "element-plus/es/components/radio/style/index",
        "element-plus/es/components/row/style/index",
        "element-plus/es/components/scrollbar/style/index",
        "element-plus/es/components/select/style/index",
        "element-plus/es/components/skeleton-item/style/index",
        "element-plus/es/components/skeleton/style/index",
        "element-plus/es/components/step/style/index",
        "element-plus/es/components/steps/style/index",
        "element-plus/es/components/sub-menu/style/index",
        "element-plus/es/components/switch/style/index",
        "element-plus/es/components/tab-pane/style/index",
        "element-plus/es/components/table-column/style/index",
        "element-plus/es/components/table/style/index",
        "element-plus/es/components/tabs/style/index",
        "element-plus/es/components/tag/style/index",
        "element-plus/es/components/text/style/index",
        "element-plus/es/components/time-picker/style/index",
        "element-plus/es/components/time-select/style/index",
        "element-plus/es/components/timeline-item/style/index",
        "element-plus/es/components/timeline/style/index",
        "element-plus/es/components/tooltip/style/index",
        "element-plus/es/components/tree-select/style/index",
        "element-plus/es/components/tree/style/index",
        "element-plus/es/components/upload/style/index",
        "element-plus/es/components/watermark/style/index",
        "element-plus/es/components/checkbox-button/style/index",
        "element-plus/es/components/space/style/index",
      ],
    },
    esbuild: isProduction
      ? {
          drop: ["console", "debugger"],
        }
      : undefined,
    // 构建配置
    build: {
      chunkSizeWarningLimit: 2000, // 消除打包大小超过500kb警告
      reportCompressedSize: false,
      minify: isProduction ? "esbuild" : false, // 只在生产环境启用压缩
      rollupOptions: {
        output: {
          // manualChunks: {
          //   "vue-i18n": ["vue-i18n"],
          // },
          // 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]表示该文件内容hash值
          entryFileNames: "js/[name].[hash].js",
          // 用于命名代码拆分时创建的共享块的输出命名
          chunkFileNames: "js/[name].[hash].js",
          // 用于输出静态资源的命名,[ext]表示文件扩展名
          assetFileNames: (assetInfo: any) => {
            const info = assetInfo.name.split(".");
            let extType = info[info.length - 1];
            // console.log('文件信息', assetInfo.name)
            if (/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/i.test(assetInfo.name)) {
              extType = "media";
            } else if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(assetInfo.name)) {
              extType = "img";
            } else if (/\.(woff2?|eot|ttf|otf)(\?.*)?$/i.test(assetInfo.name)) {
              extType = "fonts";
            }
            return `${extType}/[name].[hash].[ext]`;
          },
        },
      },
    },
    define: {
      __APP_INFO__: JSON.stringify(__APP_INFO__),
    },
  };
});
相关推荐
hoLzwEge14 小时前
解码 IDE 智能提示:jsconfig.json 辅助开发全攻略
前端·前端框架
gis开发之家17 小时前
《Vue3 从入门到大神35篇》Vue3 源码详解(五):effect 依赖收集原理——track 与 trigger 是如何工作的?
javascript·typescript·前端框架·vue3·vue3源码
橘子星18 小时前
我一个前端切图仔,凭什么能在浏览器里跑大模型?
前端·javascript·前端框架
腻害兔20 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:ERP 企业资源模块,一个轻量级进销存的完整实现?
前端·javascript·vue.js·人工智能·前端框架·产品经理·ai编程
小林ixn1 天前
从 onclick 到 React 合成事件,再到完整应用逻辑:一次前端架构的深度剖析
前端·react.js·前端框架
hoLzwEge2 天前
前端环境变量配置指南:.env 文件详解
前端·前端框架
hoLzwEge2 天前
团队协作的隐藏利器:.vscode 完全指南
前端·前端框架
crary,记忆2 天前
React Hook 浅学 2.0 - 自定义Hook
前端·react.js·前端框架
小林ixn2 天前
在浏览器跑通 15 亿参数大模型:我用 React + WebGPU 复刻了 DeepSeek-R1
前端·react.js·前端框架
索西引擎3 天前
【React】useState 状态更新机制:批量更新策略与“异步“错觉的深层解析
前端·react.js·前端框架