viteを使って環境構築してみた

開発環境の構築って難しい。
viteで簡単に開発環境が作れないか調べてみた。

# 作成したい環境
今回作成する環境は以下
* 作業はsrcディレクトリ配下で行う
* build時はdist配下に出力 
* SCSSの使用
* JS/CSS/画像はassets配下で管理

# プロジェクト作成手順
## 実行環境
node v20.14.0
npm 10.7.0

## ディレクトリ構成
```
dist/
src/
  ├── about
  │   └── about.html
  ├── assets
  │   ├── js
  │   │   ├── all.js
  │   │   └── counter.js
  │   └── styles
  │       ├── foundation
  │       │     └── _base.scss
  │       │     └── _index.scss
  │       ├── pages
  │       │     └── _about.scss
  │       │     └── _index.scss
  │       └── style.scss
  ├── public
  │   └── assets
  │       └── img
  │            ├── javascript.svg
  │            └── vite.svg
  └── index.html
package.json
vite.config.js
```

## viteと必要なプラグインのインストール
viteのプロジェクト作成
```:ターミナル
npm create vite@latest vite-project-for-static-site
✔ Select a framework: › Vanilla
✔ Select a variant: › JavaScript
```
sassとsassのパーシャルファイル(_アンダースコアから始まるファイル)を管理する用のインストール
```:ターミナル
npm i sass
npm i vite-plugin-sass-glob-import
```

vite.config.jsのinputに記述する項目をページが増えても自動的にディレクトリ取得してくれるプラグインのインストール
```:ターミナル
npm i glob
```

## vite.config.jsを作成してbuild設定
```vite.config.js
import { globSync } from "glob";
import path, { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { defineConfig } from "vite";
import sassGlobImports from 'vite-plugin-sass-glob-import';

// js,css,htmlの出力先をそれぞれに指定するための元のディレクトリの取得するための記述
const jsFiles = Object.fromEntries(
  globSync('src/**/*.js', { ignore: ['node_modules/**','**/modules/**','**/dist/**']}).map(file => [
    path.relative(
      'src',
      file.slice(0, file.length - path.extname(file).length)
    ),
    fileURLToPath(new URL(file, import.meta.url))
  ])
);

const scssFiles = Object.fromEntries(
  globSync('src/assets/styles/pages/**/*.scss', { ignore: ['src/assets/styles/pages/**/_*.scss'] }).map(file => [
    path.relative(
      'src',
      file.slice(0, file.length - path.extname(file).length)
    ),
    fileURLToPath(new URL(file, import.meta.url))
  ])
);

const htmlFiles = Object.fromEntries(
  globSync('src/**/*.html', { ignore: ['node_modules/**', '**/dist/**'] }).map(file => [
    path.relative(
      'src',
      file.slice(0, file.length - path.extname(file).length)
    ),
    fileURLToPath(new URL(file, import.meta.url))
  ])
);

const inputObject = { ...scssFiles, ...jsFiles, ...htmlFiles };

export default defineConfig({
    // srcディレクトリをrootにする指定
    root: "src",
    // ビルド設定
    build: {
        // ビルド出力先はdist
        outDir: resolve(__dirname, "dist"),
        // 中身が空のファイルでも出力する
        emptyOutDir: true,
        // js,css,htmlの出力先をそれぞれに指定
        rollupOptions: {
          // 出力元のファイル
          input: inputObject,
          // 出力先のファイル名指定
          output: {
            entryFileNames: `[name].js`,
            chunkFileNames: `[name].js`,
            assetFileNames: (assetInfo) => {
              if (/\.( gif|jpeg|jpg|png|svg|webp| )$/.test(assetInfo.name)) {
                return 'assets/img/[name].[ext]';
              }
              if (/\.css$/.test(assetInfo.name)) {
                return 'assets/css/[name].[ext]';
              }
              return 'assets/[name].[ext]';
            }
          },
        }
    },
    // 使用するプラグインの記述
    plugins: [
      sassGlobImports()
    ],
    // localhostのポート番号指定
    server: {
      port: 3000
    }
})
```

rollupOptionsのinputなどは以下の参考サイトからそのまま使用させていただいた。
ここまでの設定でHTMLはそれぞれ別ファイルでも出力されるようになったし、SCSSも使用できるようになった。もちろんdistにはコンパイルされて一つのCSSファイルとして出力される。
jsはバンドルして１ファイルにしたいとか、画像ファイルの出力先の指定がうまくできないといった問題は残るがgulpやwebpackよりもエラーにぶつからず構築できた。

ここまでの環境はgithubに残しました。
https://github.com/Maro1027/vite-project-for-static-site


# 参考サイト
https://ja.vitejs.dev/

https://qiita.com/takegons/items/13bef7efe9aa8a9cefde

https://zenn.dev/deguchihi/articles/aec6c0eed7a9f6#vite.config.js%E4%BD%9C%E6%88%90

https://yuito-blog.com/vite-develop/#index_id12