I'm facing an issue with organizing assets in the output directory while using Vite for my project. I've configured the output.assetFileNames
option to organize assets into subdirectories based on their types (css, fonts, img, js), but it's not working as expected.
this my Vite Configuration:
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}`;
},
},
},
},
});
i was tring many thing but this is the colse structure with this config
Project Structure:
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
Expected Output:
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
Issue:
Despite configuring the output.assetFileNames
function, the assets are not being organized into the specified subdirectories. I've checked the file extensions, reviewed the Vite configuration, and tried running a clean build, but the issue persists.
I appreciate any help in resolving this issue. If you need more information, please let me know. Thank you!
For the files considered assets – which s all files apart from the index-….js
and index.html
file – their locations can indeed be modified via the assetFileNames
. If we look at the documentation form output.assetFileNames
:
Type: Type: string| ((assetInfo: AssetInfo) => string)
[…]
When using a function,
assetInfo
is a reduced version of the one ingenerateBundle
without thefileName
.
And when we look at generateBundle
:
interface OutputAsset { fileName: string; name?: string; needsCodeReference: boolean; source: string | Uint8Array; type: 'asset'; }
And if we look at the source code of Rollup where assetFileNames
is called:
typeof outputOptions.assetFileNames === 'function' ? outputOptions.assetFileNames({ name, source, type: 'asset' }) : outputOptions.assetFileNames,
We see that ext
is not a property that exists in the object parameter passed to the assetFileNames
. This means that for your function:
assetFileNames: ({ name, ext }) => {
ext
will be undefined
for all asset files and thus none of the code paths within the if
statements will be visited. Instead, consider querying the extension yourself like:
// …
import path from 'node:path';
// …
export default defineConfig({
// …
build: {
// …
rollupOptions: {
output: {
assetFileNames: ({ name }) => {
const ext = path.extname(name);
For the index-gT3gkYz_.js.map
sourcemap file, you'd need to use the output.sourcemapFileNames
Rollup option like:
// …
export default defineConfig({
// …
build: {
// …
rollupOptions: {
output: {
// …
sourcemapFileNames: 'assets/js/[name].[hash].js.map',