Vite - change ouput directory of assets
Asked Answered
H

4

19

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?

Hexagon answered 18/2, 2022 at 22:27 Comment(0)
A
54

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

Adsorbent answered 20/2, 2022 at 1:10 Comment(1)
This works well except I changed it to assetInfo.name.split('.').at(-1) to get the last item in the array instead of the 2nd. In my case there was a . in my user folder name that broke it.Absalom
H
7

If you use @font-face in your css file, it masses up. 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",
      },
    }

Hexagon answered 27/4, 2022 at 6:30 Comment(0)
S
5

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];
Shemeka answered 25/3, 2022 at 9:4 Comment(1)
Honestly you should use .pop() to remove the last element from the array, since there can be more than one dot and then this hardcoded [1] index won't workUrsa
P
5

Suddenly someone will need it.
I have a separate folder configured in my assembly for different types of files.
All that is required is: npm i sass, npm i vite
vite.config.js

import { defineConfig } from 'vite';

export default defineConfig({
  root: './src',
  build: {
    outDir: '../dist',
    assetsDir: '', // Leave `assetsDir` empty so that all static resources are placed in the root of the `dist` folder.
    assetsInlineLimit: 0,
    rollupOptions: {
      // input: {
      //   // Uncomment if you need to specify entry points for .html files
      //   index: resolve(__dirname, 'src/index.html'),
      //   myworks: resolve(__dirname, 'src/my-works.html'),
      //   thoughts: resolve(__dirname, 'src/thoughts.html'),
      //   about: resolve(__dirname, 'src/about.html'),
      //   contact: resolve(__dirname, 'src/contact.html'),
      // },
      output: {
        entryFileNames: 'js/[name]-[hash].js', // If you need a specific file name, comment out
        chunkFileNames: 'js/[name]-[hash].js', // these lines and uncomment the bottom ones
        // entryFileNames: chunk => {
        //   if (chunk.name === 'main') {
        //     return 'js/main.min.js';
        //   }
        //   return 'js/main.min.js';
        // },
        assetFileNames: assetInfo => {
          const info = assetInfo.name.split('.');
          const extType = info[info.length - 1];
          if (/\.(png|jpe?g|gif|svg|webp|webm|mp3)$/.test(assetInfo.name)) {
            return `media/[name]-[hash].${extType}`;
          }
          if (/\.(css)$/.test(assetInfo.name)) {
            return `css/[name]-[hash].${extType}`;
          }
          if (/\.(woff|woff2|eot|ttf|otf)$/.test(assetInfo.name)) {
            return `fonts/[name]-[hash].${extType}`;
          }
          return `[name]-[hash].${extType}`;
        },
      },
    },
  },
});

main.js

import '../scss/style.scss'

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <link rel="stylesheet" href="scss/style.scss" /> ".scss styles can be included in html and not in main.js" -->
    <title class="dawd">Starter_Vite</title>
  </head>
  <body>
    <div id="app"><p class="dawd">Lorem ipsum dolor sit amet.</p></div>
    <script type="module" src="js/main.js"></script>
  </body>
</html>

Raw directory and file structure.

   Starter_Vite
    ├── .gitignore
    ├── package.json
    ├── vite.config.js
    └── src
        ├── index.html
        ├── fonts
        │   ├── iosevka-ss11-extendedthin.ttf
        │   ├── MuseoCyrl-500.otf
        │   └── MuseoCyrl-500.woff2
        ├── js
        │   └── main.js
        ├── media
        │   └── 0.webp
        └── scss
            ├── style.scss
            └── _fonts.scss

Structure of directories and files of the finished assembly.

dist
├── index.html
├── css
│   └── index-113614d4.css
├── fonts
│   ├── iosevka-ss11-extendedthin-550d1ad8.ttf
│   ├── MuseoCyrl-500-8f1dc1cc.otf
│   └── MuseoCyrl-500-dc3a33d1.woff2
├── js
│   └── index-190da3b7.js
└── media
    └── 0-21ab3b1b.webp
Presnell answered 15/7, 2023 at 20:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.