性能优化-Vue3 + Vite:图片上传/优化到 OSS 并统一使用vite 的 .env 全局配置,js 和 css 共用变量
在前端项目中,图片资源的管理是非常常见的问题:
-
图片可能需要放在 OSS/CDN 上以提高访问速度
-
不同环境可能对应不同的 OSS 地址
-
样式中可能需要用到这些图片路径
本文将以 上传/优化图片到 OSS 为例,介绍如何:
-
使用
.env
文件统一管理 OSS 地址。 -
在 Vue 组件和 JS/TS 文件中访问 OSS 地址。
-
将 OSS 地址同步到 SCSS 变量,方便样式统一管理。
一、环境变量配置 .env
在 Vite 中,不同环境可以用不同的 .env
文件:
# .env.development
VITE_OSS_BASE_URL=https://dev-oss.example.com# .env.production
VITE_OSS_BASE_URL=https://oss.example.com
注意:Vite 要求变量必须以
VITE_
前缀开头才能在代码中访问。
1.1 多环境公用同一个配置
一般来说,对于图片这种静态资源,不同的环境地址都是相同的,所以我们可以写一个多个环境公用的配置文件,即 .env 文件。
# .env (通用配置)
VITE_OSS_BASE_URL=https://oss.example.com
# .env.dev
VITE_API_BASE_URL=https://dev-api.xxx.com
VITE_ENV=dev
需求 | 推荐做法 |
---|---|
所有环境通用的变量 | 放在 .env |
各环境不同的变量 | 放在 .env.dev 、.env.prod 等 |
避免重复修改 | 永远在 .env 放公共变量 |
二、在 JS/TS 中访问 OSS 地址
在项目中创建一个全局配置文件:
// src/config/index.ts
export const OSS_BASE_URL = import.meta.env.VITE_OSS_BASE_URL;
然后在组件中使用:
<template><img :src="logoUrl" alt="Logo" />
</template><script setup lang="ts">
import { OSS_BASE_URL } from '@/config';const logoUrl = `${OSS_BASE_URL}/images/logo.png`;
</script>
这样,无论切换到开发环境还是生产环境,图片路径都会自动对应不同环境的 OSS 地址。
三、在 SCSS 中使用 OSS 地址
如果需要在样式中引用 OSS 图片,例如背景图,可以通过 vite.config.ts
注入变量:
Vite 中要把环境变量注入 SCSS,需要注意几点:
-
loadEnv
必须在函数中调用
因为 Vite 只有在配置函数执行时才会知道当前mode
,所以你不能直接在顶层调用loadEnv
。 -
export default defineConfig
需要传函数
如果你直接写成export default defineConfig({ ... })
,就无法动态获取环境变量。正确做法是传一个函数:
// vite.config.ts
import { defineConfig, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';export default ({ mode }) => {const env = loadEnv(mode, process.cwd());return defineConfig({plugins: [vue()],css: {preprocessorOptions: {scss: {additionalData: `$oss-base-url: "${env.VITE_OSS_BASE_URL}";`}}},resolve: {alias: {'@': path.resolve(__dirname, 'src')}}});
};
问题 | 说明 |
---|---|
loadEnv 调用时机 | 必须在函数内部获取 mode ,因为顶层无法确定当前环境 |
export default defineConfig({ ... }) 直接传对象 | 不行,因为无法动态注入环境变量 |
正确方式 | export default ({ mode }) => defineConfig({ ... }) |
然后在 SCSS 中使用:
// src/styles/global.scss
.banner {background-image: url(#{$oss-base-url}/images/banner.jpg);background-size: cover;background-position: center;
}
additionalData
会在每个 SCSS 文件顶部注入 $oss-base-url
,无需手动 @import
。
四、在 index.html
中使用 OSS 地址
在 Vite 中,如果你希望在 index.html
中如果用到这个图,暂没有便捷方法直接引用环境变量,所以需要直接手动写这个 oss 地址。
五、示例:图片上传和优化到 OSS
假设有一个组件可以拖拽上传图片,并将其上传到 OSS:
<template><div class="upload-wrapper"><input type="file" @change="uploadImage" /><img v-if="imageUrl" :src="imageUrl" alt="Uploaded Image" class="uploaded-image" /><div class="banner"></div></div>
</template><script setup lang="ts">
import { ref } from 'vue';
import axios from 'axios';
import { OSS_BASE_URL } from '@/config';const imageUrl = ref('');async function uploadImage(event: Event) {const target = event.target as HTMLInputElement;if (!target.files?.length) return;const file = target.files[0];const formData = new FormData();formData.append('file', file);try {const { data } = await axios.post(`${OSS_BASE_URL}/upload`, formData);// 假设返回对象中包含上传后的完整路径imageUrl.value = data.url;} catch (err) {console.error('上传失败', err);}
}
</script><style lang="scss" scoped>
.upload-wrapper {display: flex;flex-direction: column;gap: 16px;align-items: flex-start;.uploaded-image {width: 200px;height: auto;border: 1px solid #ddd;}.banner {width: 100%;height: 150px;background-image: url(#{$oss-base-url}/images/banner.jpg);background-size: cover;background-position: center;border-radius: 8px;}
}
</style>
这样做的好处:
-
图片上传和访问路径统一管理
-
切换环境时无需修改代码
-
样式和 JS/TS 文件都可以共用同一个 OSS 地址变量
六、总结
通过本文方法,你可以实现:
-
全局 OSS 地址管理:通过
.env
文件统一管理多环境 OSS 地址。 -
JS/TS 访问方便:通过配置文件或
import.meta.env
获取路径。 -
SCSS 同步变量:通过
vite.config.ts
注入,方便样式中直接引用。 -
环境切换无痛:开发/生产环境自动切换,无需手动修改路径。