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__),
    },
  };
});
相关推荐
星栈16 小时前
写 Dioxus Demo 不难,难的是把它写成项目
前端·rust·前端框架
用户2204603958682 天前
HBuilder + uniapp 项目切换到VsCode
前端框架
薛定喵的谔2 天前
我开源了一个精致的 Next.js 博客模板:Skyplume
前端·前端框架·next.js
星栈2 天前
我用 Rust + Dioxus 做了个全栈跨平台笔记应用:再把新建、编辑和交付补上
前端·rust·前端框架
donecoding2 天前
3 条命令搞定闭环 Monorepo:Lerna 版本管理 + 拓扑构建 + 自定义分发
前端·前端框架·node.js
星栈3 天前
我用 Rust + Dioxus 做了个全栈跨平台笔记应用:第一版先把列表和详情跑通
前端·rust·前端框架
下家4 天前
我放弃了 Vue/React,选择自研框架
前端·前端框架
hoLzwEge4 天前
pnpm-lock.yaml
前端框架
星栈4 天前
Dioxus 接数据库最容易写歪的 3 个地方:sqlx + SQLite 怎么接才顺
前端·rust·前端框架
星栈4 天前
Dioxus 表单处理:从输入、校验到文件上传,一条链路讲透
前端·rust·前端框架