'Vite - change ouput directory of assets

By default Vite generates files in the source directory under dist.

my-app/
├─ node_modules/
├─ dist/
│  ├─ assets/
|  |    | index.js
|  |    | index.css        
│  ├─ index.html
├─ index.html
├─ main.js
├─ style.scss
├─ package.json

I need to create a different folder for js and css files under assets. In other words, I need to put js and css filer under /assets/js and /assets/css folders respectively.

my-app/
├─ node_modules/
├─ dist/
│  ├─ assets/
|  |    |-js/
|  |    |   index.js
|  |    |-css/
|  |    |  index.css  

This is my config file.

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgrPlugin from "vite-plugin-svgr";

// https://vitejs.dev/config/
export default defineConfig({
  base: "./",
  plugins: [react(), svgrPlugin()],
  server: {
    open: true,
    proxy: {
      "/base": {
        target: "http://localhost:19000",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/base/, ""),
      },
    },
  },
});

How to do so?



Solution 1:[1]

The output filenames are configured in Rollup with build.rollupOptions:

  1. Set output.assetFileNames to configure the asset filenames (for media files and stylesheets).

  2. Set output.chunkFileNames to configure the vendor chunk filenames.

  3. Set output.entryFileNames to configure the index.js filename.

// vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      output: {
        1??
        assetFileNames: (assetInfo) => {
          let extType = assetInfo.name.split('.').at(1);
          if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
            extType = 'img';
          }
          return `assets/${extType}/[name]-[hash][extname]`;
        },
        2??
        chunkFileNames: 'assets/js/[name]-[hash].js',
        3??
        entryFileNames: 'assets/js/[name]-[hash].js',
      },
    },
  },
});

demo

Solution 2:[2]

Thanks tony19, this work properly as well, but i has build error: [vite:build-html] assetInfo.name.split(...).at is not a function

I simple change

assetInfo.name.split('.').at(1);

to

assetInfo.name.split('.')[1];

Solution 3:[3]

Should you have used @font-face in your css file, it masses up. So you may need to put fonts in the same folder as the css files.

I have used woff and woff2 fonts

    rollupOptions: {
      output: {
        assetFileNames: (assetInfo) => {
          var info = assetInfo.name.split(".");
          var extType = info[info.length - 1];
          if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType)) {
            extType = "img";
          } else if (/woff|woff2/.test(extType)) {
            extType = "css";
          }
          return `static/${extType}/[name]-[hash][extname]`;
        },
        chunkFileNames: "static/js/[name]-[hash].js",
        entryFileNames: "static/js/[name]-[hash].js",
      },
    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tony19
Solution 2 Elikill58
Solution 3 mahan