Vite 构建工具

Vite 8

多环境配置 .env 文件

vue3-vite-cube/.env.development

js 复制代码
VITE_MODE=development
VITE_PAGE_TIRTLE=开发环境
VITE_URL=http://localhost:8080

vue3-vite-cube/.env.production

js 复制代码
VITE_MODE=production
VITE_PAGE_TIRTLE=生产环境
js 复制代码
<template>
  <div>
    <h1>EnvA</h1>
    <p>当前环境:{{ mode }} - {{ pageTitle }}</p>
  </div>
</template>

<script setup lang="ts">
const mode = import.meta.env.VITE_MODE;
const pageTitle = import.meta.env.VITE_PAGE_TIRTLE;
defineOptions({
  name: "EnvA",
});
</script>

本地开发环境

打印 import.meta 结果

编译文件

example

js 复制代码
const key = "VITE_PAGE_TIRTLE";
const mode = import.meta.env.VITE_MODE;
const pageTitle = import.meta.env[key];

编译文件

生产开发环境

打印 import.meta 结果

打包后文件

example

js 复制代码
const key = "VITE_PAGE_TIRTLE";
const mode = import.meta.env.VITE_MODE;
const pageTitle = import.meta.env[key];

打包后文件

开发服务器 server

https 访问项目 (启用 TLS + HTTP/2)

1、 利用 server.https 配置证书

server.https 该值是传递给 https.createServer() 的 options 对象。

js 复制代码
 server: {
      https: {
        key: fs.readFileSync(path.join(__dirname, './ssl/private-key.pem')),
        cert: fs.readFileSync(path.join(__dirname, './ssl/certificate.pem'))
      },
 }

2、利用 @vitejs/plugin-basic-ssl 插件, 插件地址

js 复制代码
import basicSsl from '@vitejs/plugin-basic-ssl';

plugins: [
  basicSsl()
]

代理 https 后端

1、前端利用 http 访问 (http1.1 协议)

前端项目 http://localhost:5173/vue3-vite-cube/cloud/vueKnown

后端项目 https://localhost:8443/api (express + https HTTP1.1)

js 复制代码
proxy: {
  // 对象配置
  '/api1': {
    target: 'https://localhost:8443/api',
    changeOrigin: true,
    secure: false,
    rewrite: (path) => path.replace(/^\/api1/, ''),
  },
 }
js 复制代码
const fetchData = async () => {
  const response = await fetch("https://localhost:8443/api/user");
  console.log("response", response);
};

const fetchData2 = async () => {
  const response = await fetch("/api1/user");
  console.log("response2", response);
};

跨域请求,用了 https 方案 ; 同源请求, 使用 http 方案; 都是使用了 http1.1

2、 前端使用 https 访问 (h2 协议)

前端项目 https://localhost:5173/vue3-vite-cube/cloud/vueKnown

后端项目 https://localhost:8443/api (express + https HTTP.1)

js 复制代码
const fetchData = async () => {
  const response = await fetch("https://localhost:8443/api/user");
  console.log("response", response);
};

const fetchData2 = async () => {
  const response = await fetch("/api1/user");
  console.log("response2", response);
};

跨域和同源访问都使用了 https 方案。 跨域实例了 http1.1 协议 , 同源使用了 h2 协议

代理 http/2 后端 (node http/2)

前端项目 https://localhost:5173/vue3-vite-cube/cloud/vueKnown

后端项目 https://localhost:8843/api (HTTP/2)

前端请求 http/2 后端接口,解决跨域配置代理,需要使用 vite-plugin-proxy-http2, 由于 在开发环境下,同时开启 https 服务和 proxy 代理时,请求会被降级为 HTTP/1.1

js 复制代码
import proxyHttp2 from 'vite-plugin-proxy-http2'

plugins:[
    proxyHttp2({
      proxy: {
        '/api2': {
          target: 'https://localhost:8843/api', // http/2
          changeOrigin: true,
          secure: false,
          rewrite: (path) => path.replace(/^\/api2/, '/api'),
        },
      },
    }),
 ]
js 复制代码
curl -k https://localhost:8443/api/user
curl -k https://localhost:8843/api/user

预览配置 preview

命令参数

js 复制代码
cli
  .command('preview [root]', 'locally preview production build')
  .option('--host [host]', `[string] specify hostname`, { type: [convertHost] })
  .option('--port <port>', `[number] specify port`)
  .option('--strictPort', `[boolean] exit if specified port is already in use`)
  .option('--open [path]', `[boolean | string] open browser on startup`)
  .option('--outDir <dir>', `[string] output directory (default: dist)`)
  .action(){
  }

配置文件配置项

ts 复制代码
interface CommonServerOptions {

  port?: number;

  strictPort?: boolean;

  host?: string | boolean;

  allowedHosts?: string[] | true;

  https?: HttpsServerOptions;

  open?: boolean | string;
  /**
  * Configure custom proxy rules for the dev server. Expects an object
  * of `{ key: options }` pairs.
  * Uses [`http-proxy-3`](https://github.com/sagemathinc/http-proxy-3).
  * Full options [here](https://github.com/sagemathinc/http-proxy-3#options).
  *
  * Example `vite.config.js`:
  * ``` js
  * module.exports = {
  *   proxy: {
  *     // string shorthand: /foo -> http://localhost:4567/foo
  *     '/foo': 'http://localhost:4567',
  *     // with options
  *     '/api': {
  *       target: 'http://jsonplaceholder.typicode.com',
  *       changeOrigin: true,
  *       rewrite: path => path.replace(/^\/api/, '')
  *     }
  *   }
  * }
  * ```
  */
  proxy?: Record<string, string | ProxyOptions>;
  /**
  * Configure CORS for the dev server.
  * Uses https://github.com/expressjs/cors.
  *
  * When enabling this option, **we recommend setting a specific value
  * rather than `true`** to avoid exposing the source code to untrusted origins.
  *
  * Set to `true` to allow all methods from any origin, or configure separately
  * using an object.
  *
  * @default false
  */
  cors?: CorsOptions | boolean;

  headers?: OutgoingHttpHeaders;
}

Vite 5

示例 element-plus 全局注册 & 按需加载

全局注册(首页加载)

vue3-mananger/vite.config.ts build 使用 vite 默认配置

构建结果

首页 lighthouse 结果

element-plus 按需引用 (首页加载)

首页加载

构建结果

lighthouse

示例 富文本组件 & UI组件库

全局注册UI组件

vue3-td-vite3/vite.config.ts 使用 vite 默认配置

组件全局注册,富文本只有一个组件使用

构建结果

lighthouse

Lighthouse Treemap

多个组件使用富文本插件后

UI组件还是 全局注册组件,可以看出 富文本插件 @wangeditor/editor@wangeditor/editor-for-vue 打包成一个文件。

之前 创建文章页面资源加载

多个组件使用富文本组件,再看创建文章页面加载

  • Vite 会自动 去重 ,将所有相同的 CSS 合并到一个文件中
  • 最终只输出一份 style.css ,不会重复打包

富文本插件按需加载

js 复制代码
// 动态导入富文本编辑器,减少首屏加载
const Editor = defineAsyncComponent(() =>
  import('@wangeditor/editor-for-vue').then((m) => m.Editor)
)
const Toolbar = defineAsyncComponent(() =>
  import('@wangeditor/editor-for-vue').then((m) => m.Toolbar)
)

构建结果

示例 手动拆分富文本插件

js 复制代码
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // wangEditor 富文本编辑器
          'wangeditor': ['@wangeditor/editor' ],
          'wangeditor-vue': ['@wangeditor/editor-for-vue']
        }
      }
    }
  }

手动指定拆分包

build.rollupOption.manualChunks

js 复制代码
manualChunks: {
  // Vue 全家桶
  'vue-vendor': ['vue', 'vue-router', 'pinia'],
  // TDesign UI 组件库
  'tdesign': ['tdesign-vue-next', 'tdesign-icons-vue'],
  // wangEditor 富文本编辑器
  'wangeditor': ['@wangeditor/editor', '@wangeditor/editor-for-vue']
}

@wangeditor/editor 核心包(804 kB)本身是预打包的库,无法在 Vite 层面进一步拆分。

js 复制代码
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          // Vue 核心库
          if (id.includes('node_modules/vue/') || id.includes('node_modules/vue-router/')) {
            return 'vue-vendor'
          }
          // TDesign UI 组件库
          if (id.includes('node_modules/tdesign-vue-next/')) {
            return 'tdesign'
          }
          // wangEditor 富文本编辑器核心
          if (id.includes('node_modules/@wangeditor/editor/')) {
            return 'wangeditor'
          }
          // wangEditor Vue 组件
          if (id.includes('node_modules/@wangeditor/editor-for-vue/')) {
            return 'wangeditor-vue'
          }
          // 其他第三方库
          if (id.includes('node_modules/')) {
            return 'vendor'
          }
        }
      }
    }
  }

模块信息

js 复制代码
interface ModuleInfo extends ModuleOptions {
	ast: ProgramNode | null;
	code: string | null;
   // 谁动态引用了当前模块? 如果列表不为空,说明该模块是懒加载的(import()),应归类为非首屏资源
	dynamicImporters: readonly string[];
	dynamicallyImportedIdResolutions: readonly ResolvedId[];
	dynamicallyImportedIds: readonly string[];
	exportedBindings: Record<string, string[]> | null;
   // 如果导出列表为空但体积很大,说明该模块没有 ESM 导出,无法 Tree Shaking
	exports: string[] | null;
	safeVariableNames: Record<string, string> | null;
	hasDefaultExport: boolean | null; //是否有 export default
	id: string; // 模块id ,绝对路径
	implicitlyLoadedAfterOneOf: readonly string[];
	implicitlyLoadedBefore: readonly string[];
	importedIdResolutions: readonly ResolvedId[];
	importedIds: readonly string[]; // 当前模块同步/异步引用了哪些模块
	importers: readonly string[]; // 哪些模块引用了当前模块
	isEntry: boolean;// 是否入口文件,true代表一定要首屏包内
	isExternal: boolean;// 是否外部文件
    //  true,代码会进入最终的 .js
    // false,说明 Vite/Rollup 通过 Tree Shaking 判定它没有被使用,已被丢
	isIncluded: boolean | null;
}

环境变量配置

最后

相关推荐
moMo4 天前
我用的脚手架到底是什么——Vite 主要功能
vite
To_OC5 天前
通义千问多模态生图踩坑记:我是如何把两个报错逐个干翻的
前端·aigc·vite
梵得儿SHI6 天前
Vue 项目实战与性能优化全攻略:从代码、渲染到首屏,一站式解决卡顿慢加载
前端·vue.js·性能优化·vite·前端面试·前端优化·首屏优化
天蓝色的鱼鱼8 天前
Vite 8 换上 Rolldown 后,前端构建真的会快很多吗?
前端·vite
裕波9 天前
Vue&ViteConf 2026 将于 7 月 18 日在上海举办,尤雨溪将现场发表主题演讲
vue.js·vite
鲁班小子10 天前
Vite resolve.dedupe 使用教程
vue.js·vite
kyriewen14 天前
从Webpack到Vite:我们迁移了一个10万行代码的项目,总结了这7个坑
前端·webpack·vite
大家的林语冰14 天前
尤雨溪官宣:Vite+ 全员加盟 Cloudflare,正式进军全栈开发和 AI 部署云平台!
前端·javascript·vite
明月_清风15 天前
爆破前端生态!Cloudflare 收购 Vite 背后,前端开发者会迎来什么变化?
前端·vite