UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【Vite】複数ページある場合の設定を考える

ViteはマルチページAppに対応しているので、複数ページの設定を調査した

Building for Production | Vite

マルチページAppとは上の図にあるように/だけではなく、/nest/というページがあるようなアプリケーション

やりかたはvite.config.jsrollupOptions.inputにエントリーポイントとして複数の.htmlファイルを指定するだけとある

// vite.config.js
const { resolve } = require('path')
const { defineConfig } = require('vite')

module.exports = defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html')
      }
    }
  }
})

ただ、前回やりたかった出力されるJSファイル名変更もやる場合は、もう少し工夫が必要

【Vite】ビルドして出力されるファイル名を変えたい - UGA Boxxx

前回のままだと/assets/bundle.jsが2つ(正確には、bundle.jsとbundle2.js)ができてしまったので、設定値を変える

[name]というプレースホルダーを使えば、エントリポイントにオブジェクトでない場合はエントリポイントのファイル名(拡張子なし)が埋め込まれ、エントリポイントにオブジェクトが指定された場合はキー名が埋め込まれるらしいので使ってみる

export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html')
      },
      output: {
        entryFileNames: `assets/[name]/bundle.js`,
      }
    }
  }
})

するとassets/main/bundle.jsassets/nested/bundle.jsの2つが出力された

ただ、assets/main/bundle.jsassets/bundle.jsにしたい

いろいろ試行錯誤した結果、src/pagesを用意してそこをプロジェクトルートにした

そして、src/pages配下にサブディレクトリをつくっていく

こんな感じ

├── src
│   ├── assets
│   │   └── logo.png
│   ├── components
│   │   └── HelloWorld.vue
│   ├── env.d.ts
│   └── pages
│       ├── index.html
│       ├── App.vue
│       ├── app.ts
│       ├── nested
│       │   ├── App.vue
│       │   ├── app.ts
│       │   └── index.html
│       └── nested2
│           ├── App.vue
│           ├── app.ts
│           └── index.html

vite.config.jsは結果的にこうなった

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

const { resolve } = require('path')

// https://vitejs.dev/config/
export default defineConfig({
  root: 'src/pages', //----(1)
  plugins: [vue()],
  publicDir: resolve(__dirname, 'public'), //----(2)
  build: {
    outDir: resolve(__dirname, 'dist'), //----(3)
    emptyOutDir: true,  //----(4)
    rollupOptions: {
      input: {
        '': resolve(__dirname, 'src/pages/index.html'),
        'nested': resolve(__dirname, 'src/pages/nested/index.html'),
        'nested2': resolve(__dirname, 'src/pages/nested2/index.html')
      },
      output: {
        entryFileNames: `assets/[name]/bundle.js`,
        assetFileNames: (assetInfo) => {
          if (assetInfo.name === '.css') {  //----(5)
            return 'assets/index.css'
          }
          return `assets/[name].[ext]`
        },
        chunkFileNames: `assets/[name].js`,
      }
    }
  }
})

(1)ではsrc/pagesをプロジェクトルートにする

(2)では(1)によってpublicディレクトリの場所が見つからなくなってしまったので再定義している

(3)では(1)によって出力先のdistを明示的に定義している

(4)ではdistがプロジェクトルート外になってしまったため、ビルド時に自動でクリーンするので警告がでるようになった

falseを指定すると自動でクリーンされなくなるが、今回はしてほしいのでtrueにした

(5)がはまったところで、cssファイル名が[name].cssになるため、''をエントリーポイントのキーにしたプロパティでは.cssというファイルを出力してしまう

そこで、assetInfo.nameを使って、.cssの場合はindex.cssという名前をつけるようにした

これでいい感じに吐き出してくれるようになった

$ npm run build

> try-vite@0.0.0 build
> vue-tsc --noEmit && vite build

vite v2.9.8 building for production...
✓ 19 modules transformed.
Generated an empty chunk: "main"
../../dist/index.html                 0.32 KiB
../../dist/nested/index.html          0.53 KiB
../../dist/nested2/index.html         0.53 KiB
../../dist/assets/bundle.js    0.25 KiB / gzip: 0.21 KiB
../../dist/assets/nested/bundle.js    0.25 KiB / gzip: 0.21 KiB
../../dist/assets/nested2/bundle.js   0.26 KiB / gzip: 0.21 KiB
../../dist/assets/index.css          0.17 KiB / gzip: 0.14 KiB
../../dist/assets/nested.css          0.17 KiB / gzip: 0.14 KiB
../../dist/assets/nested2.css          0.17 KiB / gzip: 0.14 KiB