在我的项目中使用 Vite 时,我遇到了在输出目录中组织资源的问题。我已经配置了
output.assetFileNames
选项来根据资源的类型(css、字体、img、js)将资源组织到子目录中,但它没有按预期工作。
这是我的Vite配置:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import autoprefixer from 'autoprefixer';
import imagemin from 'imagemin';
import imageminWebp from 'imagemin-webp';
// Specify the input and output directories for img minify
const inputDir = './src/assets/img';
const outputDir = './dist/assets';
export default defineConfig({
server: {
host: true,
port: 8080,
open: true,
https: false,
proxy: {
'/api': {
target: 'https://jsonplaceholder.typicode.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, ''),
},
},
},
css: {
postcss: {
plugins: [
autoprefixer(), // Add CSS prefixes
],
},
},
build: {
plugins: [
vue(),//
autoprefixer(), // Add CSS prefixes
// Minify images
imagemin([`${inputDir}/*.{jpg,png}`], {
destination: outputDir,
plugins: [
imageminWebp({
quality: 75, // Adjust the quality (0 to 100)
}),
],
}),
],
assetsDir: 'assets',
minify: 'terser', // or 'esbuild' for esbuild-based minification
sourcemap: true,
cssCodeSplit: true,
rollupOptions: {
output: {
assetFileNames: ({ name, ext }) => {
// Organize assets based on file type
if (ext === '.css') {
return `assets/css/${name}`;
} else if (ext === '.woff' || ext === '.woff2') {
return `assets/fonts/${name}`;
} else if (ext === '.jpg' || ext === '.webp') {
return `assets/img/${name}`;
} else if (ext === '.js') {
return `assets/js/${name}`;
}
// For other file types, use the default output format with hash
return `assets/${name}`;
},
},
},
},
});
我尝试了很多东西,但这是这个配置的大致结构
项目结构:
dist
┣ assets
┃ ┣ arslaner.jpg
┃ ┣ arslaner.webp
┃ ┣ index-gT3gkYz_.js.map
┃ ┣ index.css
┃ ┣ rawert.jpg
┃ ┣ rawert.webp
┃ ┣ SegoeUI-VF.woff
┃ ┗ SegoeUI-VF.woff2
┣ index.html
┗ vite.svg
预期输出:
dist
┣ assets
┃ ┣ css
┃ ┃ ┗ index.css
┃ ┣ fonts
┃ ┃ ┣ SegoeUI-VF.woff
┃ ┃ ┗ SegoeUI-VF.woff2
┃ ┣ img
┃ ┃ ┣ arslaner.jpg
┃ ┃ ┣ arslaner.webp
┃ ┃ ┣ rawert.jpg
┃ ┃ ┗ rawert.webp
┃ ┗ js
┃ ┃ ┗ index-gT3gkYz_.js.map
┣ index.html
┗ vite.svg
问题: 尽管配置了
output.assetFileNames
功能,但资产并未组织到指定的子目录中。我检查了文件扩展名,检查了 Vite 配置,并尝试运行干净的构建,但问题仍然存在。
我感谢您为解决此问题提供的任何帮助。如果您需要更多信息,请告诉我。谢谢!
对于被视为 assets 的文件(除了
index-….js
和 index.html
文件之外的所有文件),它们的位置确实可以通过 assetFileNames
进行修改。如果我们查看 文档表格 output.assetFileNames
:
类型: Type: string| ((assetInfo: AssetInfo) => string)
[…]
使用函数时,
是assetInfo
中函数的简化版本,没有generateBundle
。fileName
generateBundle
时:
interface OutputAsset { fileName: string; name?: string; needsCodeReference: boolean; source: string | Uint8Array; type: 'asset'; }
如果我们查看 Rollup 的源代码,其中
assetFileNames
被调用:
typeof outputOptions.assetFileNames === 'function' ? outputOptions.assetFileNames({ name, source, type: 'asset' }) : outputOptions.assetFileNames,
我们看到
ext
不是传递给 assetFileNames
的对象参数中存在的属性。这意味着对于您的功能:
assetFileNames: ({ name, ext }) => {
ext
对于所有资产文件来说将是
undefined
,因此不会访问 if
语句中的任何代码路径。相反,请考虑自己查询扩展程序,例如:
// …
import path from 'node:path';
// …
export default defineConfig({
// …
build: {
// …
rollupOptions: {
output: {
assetFileNames: ({ name }) => {
const ext = path.extname(name);
对于
index-gT3gkYz_.js.map
源映射文件,您需要使用 output.sourcemapFileNames
汇总选项,例如:
// …
export default defineConfig({
// …
build: {
// …
rollupOptions: {
output: {
// …
sourcemapFileNames: 'assets/js/[name].[hash].js.map',