47

I am using Vite (https://vitejs.dev/) for a static multipage site. This is the default project folder structure after the build command.

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

But I want to make this a multipage site and change the input and output directory for a better organizable way like this

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

Basically, it should take the src as an input folder and output dist as a child of the my-app. When I try to do this it shows errors, then I change the scripts of the package.json into this

  "scripts": {
    "dev": "vite src",
    "build": "vite build src",
    "serve": "vite preview"
  },

This way the devcommand works fine. But the 'build' command makes the dist folder inside the src folder and does not generate other HTML files except index.html.

Now how can I fix this? Any suggestion?

Paolo
  • 20,112
  • 21
  • 72
  • 113
Shams Sujon
  • 515
  • 1
  • 4
  • 9
  • If you want to know the reason of this behavior (`dist` folder inside `src` instead of the project `root` folder), you can read this anser: https://stackoverflow.com/a/69540835/774432 – flydev Oct 14 '21 at 12:33
  • the fact that vite works out of the box so well that when trying to make a static multipage site the first thing you need to configure is the outdir is amazing! imagine your webpack config before you got to this question lol – Zachiah Jun 20 '23 at 00:06

5 Answers5

77

Create a vite.config.js file and define your project root and output directory as such:


module.exports = {
  root: 'src',
  build: {
    outDir: '../dist'
  }
}

For more info, checkout config.

rakeen
  • 1,673
  • 2
  • 13
  • 22
  • 9
    You also need to set `build.emptyOutDir` to `true`. – RedGuy11 Apr 02 '22 at 16:27
  • 1
    See DrSiemer answer. The missing point here is that the vite.config.js file needs to be in the src folder, otherwise even with the configs set properly, it won't output the dist folder outside of the src folder. – Alexandre Desroches May 27 '22 at 15:12
14

For multipage apps you need to specify each entry point.

To dynamically specify all .html files in src/ directory as the entry points you can set up your vite.config.js like this:

import path from "path";
import glob from "glob";

export default {
  root: path.join(__dirname, "src"),
  build: {
    outDir: path.join(__dirname, "dist"),
    rollupOptions: {
      input: glob.sync(path.resolve(__dirname, "src", "*.html")),
    },
  },
};

Make sure to install glob like this

npm install glob -D
KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • 10
    For other vite noobs like me, glob refers to an external npm package [glob](https://github.com/isaacs/node-glob) and you need to install it as a dev dependency first. – cascading-jox Apr 27 '22 at 10:00
  • 1
    This is the only answer I was looking for since the release of Vite. I just wanted to use Vanilla HTML with Vite just for the live preview. But multiple HTML files makes it difficult to implement. This answer solved my year long mystery. Thanks man! – Surjith S M Feb 24 '23 at 14:25
  • Do you know how to specify the chunk names? If each of your different html pages shares any code/components how can you get a duplicated chunk file for each html page or how can you preset what the chunk name should be? I'm trying to make each page of the multi page app independent, but I can't figure out the naming nomenclature. Thanks. – Jonathan Counihan Mar 16 '23 at 05:14
  • Because I have nested paths I needed to modify glob to the following: `input: glob.sync(path.resolve(__dirname, "src", "**/*.html"))` – Denis Pshenov Jun 30 '23 at 14:06
10

Make sure you add vite.config.js inside your Vite root directory (src).

    module.exports = defineConfig({
      base: '',
      root: 'src',
      build: {
        outDir: '../dist'
      }
    });

Don't forget to update your package scripts. You'll need to add the --emptyOutDir flag if you want the same behavior as in the default project structure (clear output folder before building).

    "scripts": {
      "dev": "vite src",
      "build": "vite build src --emptyOutDir",
    }
thoroc
  • 3,291
  • 2
  • 27
  • 34
DrSiemer
  • 141
  • 1
  • 5
  • 4
    It should be noted that 'emptyOutDir' is a build option as well and can be used instead of the cli flag. `build: { outDir: '../dist', emptyOutDir: true }` – thatguytyler Mar 09 '22 at 18:10
  • 1
    The most important step is what you said: the vite.config.js file MUST be in the src folder. Otherwise, I tried everything and it won't work. – Alexandre Desroches May 27 '22 at 15:10
9

If you want to use defineConfig in your vite.config.ts you can use it like this:

    import { defineConfig } from 'vite'
    import reactRefresh from '@vitejs/plugin-react-refresh'
    import eslintPlugin from 'vite-plugin-eslint'
    
    // https://vitejs.dev/config/
    export default defineConfig({
        plugins: [reactRefresh(), eslintPlugin({ cache: false })],
        root: 'src',
        build: {
            outDir: '../dist'
        }
    })
6

You can set up your vite.config.js like this:

import path from 'path'

export default {
  root: path.resolve(__dirname, 'src'),
  build: {
    outDir: path.resolve(__dirname, 'dist'),
    rollupOptions: {
      input: {
        index: path.resolve(__dirname, 'src/index.html'),
        about: path.resolve(__dirname, 'src/about.html')
      }
    }
  }
}
thoroc
  • 3,291
  • 2
  • 27
  • 34
Kobshobe
  • 89
  • 1
  • 6