Webpack設定のベストプラクティス

1. ホットリロードの設定

  1. webpack-dev-serverのインストール: npm i webpack-dev-server -D

  2. webpack.config.jsの設定 ``` module.exports = { // 他の設定項目 ...,

     // ホットリロード設定
     devServer: {
       host: "localhost",
       port: 3000,
       hot: true, // ホットリロードを有効化
     },
    

    }

    
    
    
    

2. エントリーポイントの設定:相対パスを使用

エントリーポイントはwebpackが実行されるディレクトリからの相対パスで設定する必要があります。ファイル自体のパスではありません。

3. PostCSSによるブラウザ互換性の処理

PostCSSの設定はcss-loaderの後、他のCSSプリプロセッサの前に配置する必要があります。

4. キャッシュの有効化(Babel、eslint)

// module内の設定、babel-loaderでbabelキャッシュを有効化
module:{
    rules:{
        test:/\.js$/,
        include:path.resolve(__dirname,'../src'),
        use:{
            loader:"babel-loader",
            options:{
                cacheDirectory:true, // キャッシュを有効化
                cacheCompression:false, // 圧縮を無効化
            }
        }
    }
}

// plugins内でeslintのキャッシュを有効化
plugins:[
    new ESLintPlugin({
      context: resolve("../src"),
      exclude: "node_modules",
      cache:true, // キャッシュを有効化
      // キャッシュディレクトリの指定
      cacheLocation:path.resolve(__dirname,'../node_modules/.cache/eslintcache')
    }),
]

5. コードサイズの削減

なぜ必要か
  1. Babelは各ファイルにヘルパーコードを挿入するため、コードサイズが大きくなります。
  2. Babelは_extendのような共通メソッドに非常に小さなヘルパーコードを使用します。デフォルトでは、これが必要な各ファイルに追加されます。
  3. これらのヘルパーコードを独立したモジュールとして抽出し、重複を避けることができます。
解決策

@babel/plugin-transform-runtime: Babelが各ファイルに自動でランタイムを注入するのを無効にし、代わりに@babel/plugin-transform-runtimeを導入してすべてのヘルパーコードをそこから参照します。

module:{
    rules:[
        {
             loader: "babel-loader",
             options: {
                  cacheDirectory: true,
                  cacheCompression: false,
                  plugins: ["@babel/plugin-transform-runtime"], // コードサイズ削減
             },
        }
    ]
}

6. 動的インポートに名前を付ける(動的インポートは一度でも使用されると、別個のファイルとしてバンドルされます)

document.getElementById("actionBtn").addEventListener("click", function () {
  // eslintは動的インポート構文でエラーを出すため、eslint設定ファイルを修正する必要があります
  // webpackChunkName: "calculation": webpackの動的インポートモジュール命名方式
  // "calculation"は[name]の値として表示されます。
  import(/* webpackChunkName: "calculation" */ "./modules/math.js").then(({ sum }) => {
    console.log(sum(5, 3));
  });
});
webpack.config.jsでの設定
{
    ...,
    output:{
        // エントリーファイルのバンドル出力名
        filename:"assets/js/main.js"
        // 画像、フォントなどtype:assetで処理されるリソースの命名方式
        assetModuleFilename: "assets/media/[hash:10][ext][query]",
        // 動的インポートの出力リソース命名方式
        chunkFilename:"assets/js/[name].chunk.js",
    },
    {
        test: /\.(png|jpe?g|gif|svg)$/,
        type: "asset",
        parser: {
           dataUrlCondition: {
             maxSize: 10 * 1024,
           },
         }, 
    },
    ...,
    optimization:{
        splitChunks:{
            chunks:"all"
        }
    }
}

7. ファイル内容に基づいたハッシュ値の生成(contenthash)

メインファイルに変更がなくても、参照ファイルが変更された場合でも、メインファイルのハッシュ値は変更されません。

{
    ...,
    output:{
        filename: "assets/js/[name].[contenthash:10].js", // [name]形式を使用する必要があります
    },
    ...,
    optimization:{
        ...,
        // runtimeファイルの抽出
        runtimeChunk: {
            name: (entrypoint) => `runtime~${entrypoint.name}.js`,
        },
    }
}

8. Core-jsによる構文ポリフィル(例: IE10では配列のflatメソッドがサポートされていません。@babel/preset-envではこのようなAPI問題は解決できません)

// babel-config.js
module.exports = {
  //@babel/preset-envは、ターゲット環境で必要な構文変換をマイクロマネジメントせずに最新のJavaScriptを使用できるようになるスマートなプリセットです
  presets: [
    [
      "@babel/preset-env",
      {
        useBuiltIns: "usage",
        corejs: 3,
      },
    ],
  ],
};

core-js関連の構文ファイルが出力されない場合、package.jsonのbrowserslist設定でブラウザバージョンが高すぎる可能性があります。

// package.json
{
    ...,
    "browserslist": [
    "last 2 version",
    "> 1%",
    "not dead",
    "IE 10"
  ],
}

9. webpackにおけるESLintプラグインの設定

plugins:{
    new EsLintWebpackPlugin({
      context: resolve("./src"),
      exclude: "node_modules",
      cache: true,
      cacheLocation: resolve("./node_modules/.cache/.eslintcache"),
      fix: true // 修正を自動で適用
    }),
}

プロパティ名はcontextです。contentではありません。

10. Reactにおけるbabel.config.jsの自動インポート設定

module.exports = {
  presets: [
    [
      "react-app",
      {
        runtime: "automatic",
      },
    ],
  ],
};

11. コード分割のcacheGroups設定

{
    ...,
    optimization:{
        splitChunks: {
        chunks: "all",
        cacheGroups:{
         react:{
            test:/[\\/]node_modules[\\/]react(.*)?[\\/]/,
            name:'chunk-react',
            priority:40
          },
          antd:{
            test:/[\\/]node_modules[\\/]antd[\\/]/,
            name:"chunk-antd",
            priority:30
          },
          libraries:{
            test:/[\\/]node_modules[\\/]/,
            name:"chunk-vendor",
            priority:20
          }
        }
      },
    }

}

タグ: webpack javascript frontend build-tools Babel

6月30日 16:55 投稿