目次

    1. webpackとは?

    一言で言うとwebpackはJSファイルをまとめるモジュールバンドラーです。
    「一つのファイルにまとめる」ことをバンドル(bundle)と言って、複数のファイルを一つに
    まとめて出力します。ファイルを一つにまとめると、次のようなメリットがあります。

    モジュールが使用できる


    今主流のフロントエンド開発はECMA Script形式ですが、これによってscriptタグでJSライブラリを導入していた従来の方法と比較して変数の競合や、グローバル汚染を防げる、且つ機能ごとにファイルを分割するのでコードの可読性と保守性が爆上がりします。
    さらに依存関係のあるモジュールを自動で解決してくれるので、開発者がJSやCSSファイルの読み込み順を気にする必要がないのです。

    ファイル転送の最適化


    JSファイルが複数存在することでリクエスト回数が増えて転送効率が落ちるのであれば、最初から一つのファイルに記載することも可能ですが、前述の通り可読性や保守性などの観点から非推奨です。 
    また、機能を複数ファイルに分割したままだと、ブラウザからのリクエスト回数が増えてファイル転送効率が落ちます。 
    この課題に対して、webpackを利用することで機能をファイルごとに分割しながら開発し、実行時は一つのファイルとしてブラウザに提供することが可能となります。

    他にもloaderという機能を使えば、JSだけでなく、スタイルシート画像までもバンドル可能になります。
    設定次第で、画像データの自動圧縮やホットリーロードなど目から鱗の助太刀機能が豊富に揃ってしまっています。

    前編では、webpackに以下の機能を実装し開発環境を構築していきます。

    • HTMLファイルの自動出力
    • Sassの導入
    • 画像データの表示
    • Babelの導入

    それでは早速導入していきましょう!


    2. 新規プロジェクトの作成

    まずは、新規プロジェクトを立ち上げましょう!名前はtry_webpackとします。
    (なお、今回紹介する導入方法の環境はMacOSとさせていただきます)

     % mkdir try_webpack
       % cd try_webpack


    3. nodeのバージョン確認

    パッケージマネージャーでwebpackをインストールします。
    nodeまたはyarn、どちらのパッケージマネージャーでも構わないですが今回はnodeで解説します。
    まずローカルのnpmのバージョンを最新のものに合わせましょう(v16以上を推奨します。)

    バージョンの変更方法はこちらの記事が参考になります

    nodebrewでNode.jsをインストールし、バージョンを切り替えられるようにする(for Mac)

    4. webpackのインストール

    新規プロジェクトを作成しnodeのバージョンを最新にしたら、まず初期化処理を行い、package.jsonを生成します。
    -yは対話を全てyesにしてスキップするオプションです。

       % npm init -y

    画像のようにpackage.jsonが生成できたら成功です!

    初期化が完了したら必要なモジュールをインストールします。

      % npm install --save-dev webpack webpack-cli webpack-dev-server

    webpack-cliはwebpackコマンドを使用できるようにするモジュールで、
    webpack-dev-serverはwebpackでの開発サーバーを立ち上げることができるものです。

    —save-devというオプションを入れるとpackage.jsonのdevDependenciesに
    モジュールが格納されます。
    これはコードをパッケージ化する際に影響するのですが、他の人が使えるように設定をパッケージにしたい場合はnpm install —save <モジュール名>でインストールします。

    次にディレクトリ構成を編集しましょう。画像のようにフォルダやファイルを追加します。

    TRY_WEBPACK
    |-package.json
    |-package-lock.json
    |-node_modules
    |-src(追加)
    |-js(追加)
    |-index.js(追加)
    |-app.js(追加)
    |-webpack.config.js

    webpack.config.jsはwebpackの設定を記述するためのファイルです。
    この中身はモジュールをインストールするたびにコードを書く必要があります。

    webpack.config.jsを編集します。

    const path = require("path"); // pathモジュールを読み込む

    module.exports = {
    mode: "development",
    entry: "./src/js/index.js",
    output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "./src/js/main.js",
    },
    resolve: {
    extensions: [".ts", ".tsx", ".js", ".json"],
    },
    target: ["web", "es5"],
    devServer: {
    port: 8080, // ポート番号
    static: "dist", // 静的ファイルを配布するディレクトリを指定
    open: true, // ブラウザを自動的に開くかどうか
    hot: true, // ホットリロードを有効に
    },
    };

    「あーわけわかんない!」と思ったそこのあなた。大丈夫です。解説します。
    基本的にmode: “development”のようにkeyに対してvalueを設定していきます。

    mode:
    バンドルされるファイル圧縮について設定します。
    開発モードの場合はdevelopment、本番モードの場合はproductionと記述します。

    entry: 
    エントリーポイントと言って、バンドルの起点となるファイルを設定します。
    今回はindex.jsをルートディレクトリから指定しています。

    output:
    出力先のディレクトリとファイル名を設定する場合は記述します。
    pathはpathモジュールを使用して絶対パスで出力先を指定しています。
    filenameはビルドされるファイル名を設定しています。

    resolve:
    モジュールの解決方法を指定する場合に記述します。
    今回はextensionsというオプションで拡張子を省略する設定を記述しています。

    target:
    webpackを適用させる環境を設定します。
    webはブラウザのような環境で使用するためにコンパイルし、es5は指定したECMAScriptのバージョンに合わせてコンパイルすることを意味します。

    devServer:
    webpack-dev-serverの設定項目です。

    HTMLの自動出力

    モジュールをインストールします。
    % npm install --save-dev html-webpack-plugin

    ディレクトリを編集します。

    TRY_WEBPACK
    |-package.json
    |-package-lock.json
    |-node_modules
    |-src
    | |-js
    | |-index.js
    | |-app.js
    | |-index.html(追加)
    |-webpack.config.js

    src/index.htmlを編集します。

    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="UTF-8" />
    <title>try webpack</title>
    <script defer src="./js/index.js"></script>
    </head>
    <body>
    <h1>Try webpack</h1>
    </body>
    </html>

    さらにwebpack.config.jsを編集します。

    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin"); // 追加

    module.exports = {
    // ...
    devServer: {
    port: 8080,
    static: "dist",
    open: true,
    hot: true,
    },
    // ここから追加
    plugins: [
    new HtmlWebpackPlugin({
    title: "Try webpack",
    template: path.resolve(__dirname, "./src/index.html"),
    filename: "index.html",
    }),
    ],
    // ここまで追加
    };

    // temlateとfilenameで出力先とファイル名を設定します。

    ここまでで最低限の出力する準備ができました!
    ではpackage.jsonのscriptsを編集してコマンドを簡略化してみましょう。

    packge.jsonを編集

    "scripts": { "dev": "webpack --mode development --watch & webpack-dev-server", "build": "webpack", },

    これでnpm runに続いてコマンドを使用することができます。
    npm run devで開発環境、npm run buildで本番環境が立ち上がります。

    早速ターミナルで開発環境を立ち上げてみましょう!

    % npm run dev

    自動でブラウザが開きTry webpackと表示されていたら成功です!
    このタイミングでdistというディレクトリが生成されてファイルがビルドされます。

    それではconsoleも確認してみましょう。エントリーポイントとして設定したindex.jsにapp.jsで記述したconsole.logが表示されています。

    HTMLの出力はできたので、次にスタイルシートを導入します。

    スタイルシートの導入

    webpackはJS以外のファイルを読み込もうとするとエラーが起きてしまうのでloaderという拡張機能をインストールします。
    このloaderによってCSSや画像ファイルを読み込むことが可能になります。

    モジュールをインストールします。

    % npm install --save-dev css-loader style-loader

    次にwebpack.config.jsを編集します。
    module.exports = {
    entry: './src/js/index.js',
    output: {
    ...
    },
    devServer: {
    port: 8080,
    static: 'dist',
    open: true,
    hot: true,
    },
    // ここから追加
    module: {
    rules: [
    {
    test: /\.css/,
    use: [
    {
    loader: 'style-loader',
    },
    {
    loader: 'css-loader',
    },
    ],
    },
    ],
    },
    // ここまで追加
    plugins: [
    new HtmlWebpackPlugin({
    title: 'try webpack',
    template: path.resolve(__dirname, './src/index.html'),
    filename: 'index.html',
    }),
    ],
    };

    新たにmoduleを追加してloaderのrulesを設定します。
    rulesは複数設定できるので配列の形で指定してあげます。
    testはどのファイルが対象になるのかを正規表現で記述します。
    userはどのloaderを使用するのかを指定します。

    次にディレクトリを編集します。
    TRY_WEBPACK |-dist |-package.json |-package-lock.json |-node_modules |-src | |-css(追加) | | |-style.css(追加) |    |-js | | |-index.js |    | |-app.js | |-index.html |-webpack.config.js

    src配下にcssフォルダを作成しその中にstyle.cssを作成しました。
    試しにh1タグに色をつけてみましょう。

    src/css/style.cssを編集
    h1 {
    color: red;
    }

    次にスタイルシートをindex.jsにimportします。

    src/js/index.jsを編集
    import app from "./js/test";
    import "../css/style.css"; // 追加

    console.log("This is index.js");
    app();
    これでスタイルシートが適用されるはずです!
    npm run devでサーバーを起動してブラウザを確認してみましょう!

    画像のようにTry webpackのcolorがredになっていれば成功です!


    Sassの導入

    cssのままでは作業効率が悪いのでSassを導入しましょう。
    モジュールを2つインストールしますが、モジュールの依存関係でエラーが起きるので分けてインストールしてください。

    % npm install --save-dev node-sass
    # 分けてインストール
    % npm install --save-dev sass-loader

    webpack.config.jsを編集します。
    {
    test: /\.(css|scss|sass)$/, // 変更
    use: [
    {
    loader: 'style-loader',
    },
    {
    loader: 'css-loader',
    },
    {
    loader: 'sass-loader', // 追加
    },
    ],
    }

    ファイルの拡張子とindex.js内の記述を修正します。
    TRY_WEBPACK |-dist |-package.json |-package-lock.json |-node_modules |-src | |-images | | |-test.png | |-css | | |-style.scss(修正) | |-js | | |-index.js | |  |-app.js | |-index.html |-webpack.config.js

    src/js/index.js
    import app from "./app";
    import "../css/style.scss"; // 修正

    console.log("This is index.js");

    app();

    これで準備ができました!
    npm run devでブラウザを確認して画像とスタイルが適用されていれば成功です!
    次がいよいよ最後の項目です。


    画像データの読み込み

    webpack4.x では url-loader や file-loader をインストールして画像ファイルをハンドリングしていましたが、5.xではそれらがデフォルトでサポートされています。そのため、webpack.config.jsを編集するだけで画像を読み込むことができます!

    ただ、最初にインストールしたwebpack-html-pluginの画像ファイルの指定方法がやや煩雑なので、その問題を解決するためモジュールをインストールします。

    % npm install --save-dev html-loader

    webpack.config.jsを編集します。
    module: {
    rules: [
    {
    test: /\.(css|scss|sass)$/,
    use: [
    {
    loader: 'style-loader',
    },
    {
    loader: 'css-loader',
    },
    {
    loader: 'sass-loader',
    },
    ],
    },
    // ここから追記 //
    {
    test: /\.(png|jpg|jpeg|gif)/,
    type: 'asset/resource',
    generator: {
    filename: 'images/[name][ext]',
    },
    },
    {
    test: /\.html$/i,
    loader: "html-loader",
    },
    // ここまで追記 //
    ],
    },

    これで通常通りのpathの指定方法で画像を読み込めるようになりました!
    では画像データをsrc配下に入れてみましょう。
    TRY_WEBPACK |-dist |-package.json |-package-lock.json |-node_modules |-src | |-images(追加) | | |-test.png(任意の画像ファイルを格納) | |-css | | |-style.css | |-js | | |-index.js | | |-app.js | |-index.html |-webpack.config.js

    ではindex.htmlで画像のpathを指定して、スタイルも編集してみましょう!
    <!DOCTYPE html>
    <html lang="ja">
    <head>
    <meta charset="UTF-8" />
    <title>try webpack</title>
    <script defer src="./js/index.js"></script>
    </head>
    <body>
    <h1>Try webpack</h1>
    <div class="try-webpack">
    <img src="../src/images/test.jpg" alt="" />
    </div>
    </body>
    </html>

    src/css/style.scss
    h1 {
    color: red;
    }

    .try-webpack {
    width: 800px;
    height: 800px;
    object-fit: cover;

    & > img {
    max-width: 100%;
    }
    }

    npm run devでブラウザを確認してみましょう!
    画像が表示されていれば成功です!
    前編の実装は以上になります!お疲れ様でした!

    最後に

    最後まで読んでいただきありがとうございました!
    今回は前編としてHTML、CSS、画像ファイルの出力ができるようになりました!
    次回の後編ではTypeScriptReactBabelの導入など、よりモダンフロントエンドの環境をwebpackで構築する方法をお伝えします。
    お楽しみに!

    PREV
    2022.08.10
    Need to specify how to reconcile divergent
    NEXT
    2022.09.11
    ブートストラップ グリッドの使用