🍑

[React] WebpackからViteへの置き換え(オプション設定)

2024/02/03に公開

概要

React でWebアプリやデモページを作成する際にモジュールのバンドラーとして Webpack を使用していましたが Vite へ置き換えることにしました。

移行の細かな手順の説明ではなく、Webpackからの置き換え後にViteにオプションとして設定した内容についての記録です。

背景

  • 依存ライブラリの脆弱性通知が多くなってきた
  • Vite, Reactの環境構築のしやすさ、開発体験が良かった
  • 4〜5年前に作成したものが多いため整理と勉強も兼ねてTypeScriptで書き直したい
  • ESLint, Prettierを導入してコードを整理したい

構成

Before After
言語 JavaScript TypeScript
フレームワーク React React
コンパイラ Babel Vite plugins
バンドルツール Webpack Vite
リンター - ESLint
フォーマット - Prettier

大まかな移行の流れ

パッケージを順々にインストールするよりも React, Vite, TypeScript など使用したい言語やフレームワークでボイラープレートを1つ作成して構成をまるっと入れ替えるのが早いと思います。

  1. Viteのプロジェクトを作成
    Vite, React, TypeScriptの環境構築についてはブログを書いているので良かったら参考にしてください

https://chocolat5.com/tips/react-vite-typescript-vercel-boilerplate/

  1. 各種設定ファイル、ディレクトリを入れ替え
  2. index.html、App.tsx、コンポーネントファイル等を既存のものに書き換え

設定項目(config)

レガシーブラウザ対応

レガシーブラウザへの対応はプラグイン @vitejs/plugin-legacy により可能です。

npm install @vitejs/plugin-legacy
vite.config.mts
import legacy from "@vitejs/plugin-legacy";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [legacy({ targets: ["defaults"] })],
});

ビルド後のフォルダにファイル2種が追加されました 🎉

dist
 └ assets
    ├ index-<hash>.js
+   ├ index-legacy--<hash>.js
+   ├ polyfills-legacy-<hash>.js
    ...

legacy() のデフォルトはlast 2 versions and not dead, > 0.3%, Firefox ESRです。

Vite のデフォルトの対応ブラウザ
https://vitejs.dev/guide/build.html#browser-compatibility

Autoprefixer

Viteは内部でPostCSSを使用しているため autoprefixer のみを追加します。

npm install autoprefixer

PostCSS用の設定ファイルを作成します。

postcss.config.cjs
module.exports = {
  plugins: [require("autoprefixer")],
};

ESLint の設定ファイルに追記します。

.eslintrc.json
{
  ...
  "ignorePatterns": ["vite.config.mts", "postcss.config.cjs"],
  ...
}

ビルド後のファイルにベンダープレフィックスが追加されました 🎉

/* Before build */
button {
  appearance: none;
}

/* After build */
button {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
}

assetsフォルダ内の整理

デフォルトでは画像類、css、jsファイルは全てdist/assets/内に格納されます。
src内の画像についてもsrc/assets/images/のようにしている場合でも一律でdist/assets/に格納されます。

画像類は dist/assets/images/に、cssはdist/assets/css/に格納されるようにします。

vite.config.mts
...

// https://vitejs.dev/config/
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        assetFileNames: ({ name }) => {
          if (/\.(gif|jpe?g|png|svg)$/.test(name ?? "")) {
            return "assets/images/[name]-[hash][extname]";
          }
          if (/\.css$/.test(name ?? "")) {
            return "assets/[ext]/[name]-[hash][extname]";
          }
          return "assets/[ext]/[name]-[hash][extname]";
        },
      },
    },
  }
});

npm run buildを実行するとビルド後のassets内のディレクトリが変わりました 🎉

dist
 └ assets
    ├ css
    │  └ index-<hash>.css
    ├ images
    │  └ something.svg
    └ index-<hash>.js

相対パス

ビルド後のindex.html内でのCSSやJavaScriptファイルへのリンクを相対パスにしたい場合の設定です。

export default defineConfig({
  base: "./",
  ...
});

ビルド後のファイルが相対パスになりました 🎉

<!-- Before -->
<link rel="stylesheet" crossorigin href="/assets/index-IcA59260.css">

<!-- After -->
<link rel="stylesheet" crossorigin href="./assets/index-3oi5qJUV.css">

ビルド後のファイルが格納されるフォルダ名の変更

ビルド後のファイルのフォルダ名を変更したい場合の設定です。

export default defineConfig({
  ...
  build: {
    outDir: "docs",
  },
  ...
});

Discussion