webpack使ってみる

Web制作
動点Qちゃん
動点Qちゃん

そろそろwebpack使えるようになりましょうよ・・・

動点P
動点P

・・・うん。

何回かチャレンジして、まぁ使ったことあるんですけど、ぶっちゃけよくわかってない。この際ちゃんと理解したい!と思いわからないことをつぶしながら勉強して理解(?)したことをまとめておきます。

webpackとは

webpackとはJavaScriptなどのファイルをバンドル(bundle)するモジュールバンドラーです。(モジュールとは組み合わせて使うプログラムのこと)つまりファイルを束ねて一つにしてくれるツールです。

なぜファイルを一つに束ねたいのか?

インターネットでWebサイトなどを閲覧するとき、ブラウザは「画像を見せて」とリクエストをおくり、Webサーバーは「はい送りますよ」とレスポンスを返し画像を表示するというやりとりが行われています。このやりとりが増えると表示するためにかかる時間や労力が増えるので、なるべくファイルを一つにした方が表示のパフォーマンスが上がるから、というのが主な理由です。(ファイルのサイズによってはバラバラの方がいいこともあります。)

また、コードをコンパイルトランスコンパイル(トランスパイル)、つまり違う言語に変換したり、古い言語の書きかたに変換してくれる機能もあります。

JavaScriptやCSSはブラウザによっては新しい記述が対応していなかったり、prefixをつけないと古いブラウザで表示されなかったりします。また、フレームワークやSass(cssプリプロセッサ、前処理を行うプログラム)などを使うときにも、ブラウザで表示できるよう変換してくれるので、使えるようになっておきたいツールだと思います。

でも今回はとりあえずシンプルにJavaScriptCSSトランスパイルし、ファイルをバンドルするという目的で使おうと思います。

準備

webpackはnode.js上で動作するので、まずnode.jsnpmをインストールする必要があります。node.jsとはサーバーサイドでjavascriptを実行するランタイム環境で、そもそもこのnode.jsというものが難しいので深追いするのはやめます。

とにかくwebpackを実行させるときにnode.jsのプログラムを使うからインストールしないといけないです。npmはnode.jsのパッケージマネージャーでインターネット上のnpmリポジトリなどの外部からプラグインやローダーや様々なパッケージをダウンロードしてインストールするときに使うから必要です。

必要なパッケージのインストール(windowsのコマンドプロンプトを使う場合)

■コマンドプロンプトで、package.jsonファイルを作る

作っているプロジェクトのルートディレクトリに移動し、まずpackage.jsonファイルを作成するコマンドを打ちます。

 npm init -y

ここで作成されるpackage.jsonは必要最低限の、開発するプロジェクトの依存関係を管理する、基盤となるファイルです。-yはファイルを作成する際にいろいろ質問をしてくるのを飛ばして簡易的にしてくれるコマンドなので、面倒な人は入れた方がいいです。

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

こんな感じでpackage.jsonファイルが出来ます。authorとか入力する欄がありますが、npmに公開したり、配布したりしたい人以外は特に入力する必要ないので放置でOKです。scriptsにコマンドを書いておくと便利です。

    "build": "webpack --mode development",
    "prod": "webpack --mode production"

上記は例えば、development(開発用にエラーがどこで出たのかわかりやすいが冗長)モードで出力するのか、prodction(最終的にアップロードする)モードで出力するのかでわけています。

■ローカル環境にwebpackパッケージをインストール

npm install webpack webpack-cli --save-dev
npm i -D webpack webpack-cli

i・・・installの省略形 -D・・・–save-devの省略形なので上下とも同じコマンド

webpack-cliはwebpackを実行するためのコマンドラインインターフェース(CLI)で、これがないとwebpackを実行できないんで一緒にインストールが必要。

–save-devはパッケージを “devDependencies” として保存するためのオプションで、開発時に必要なパッケージとして区別する(Webサイトを表示するときの環境では不必要)。これがないとアプリケーションの実行に必要なパッケージになってしまうのでつけてください。

インストールすると、プロジェクトのルート直下にwebpack-lock.jsonnode_modulesフォルダが入ってきます。放置でOKです。

■babelをインストールする

以下のコマンドでインストールします。

npm install babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime --save-dev   

babel-loader@babel/coreを呼び出してbabelを実行するのに使用。@babel/preset-envはjavascriptをどう対応していくかの設定で使うためインストールが必要です。@babel/plugin-transform-runtimeはランタイム関数を提供し、babelがうまく動作するようにしてくれます。–save-devで開発用にインストールします。(babelに何が必要かはコードや構成によって変わってしまうので、@babel/runtimeパッケージが必要になる場合とか、いろいろあるらしい)

polyfilのためのパッケージをインストールする

npm install regenerator-runtime core-js

これはasync awaitとか、新しい記法に対応していないブラウザのためにpolyfillをつけてくれるためのパッケージですので、core-jsregenerator-runtimeをインストールしておきます。(現在これが最適な方法なのかちょっと自信ないです。)

■cssトランスパイラ用パッケージのインストール

以下のコマンドで必要なものをインストールします。

npm install autoprefixer css-loader mini-css-extract-plugin postcss-loader --save-dev
  • autoprefixer・・・prefixをつける
  • postcss-loader・・・postcssプラグインであるautoprefixerを実行する
  • css-loader・・・WebpackがCSSファイルを読み込んで解析するために必要なローダーの1つであり、postcss-loaderとともに使用されることが多いが、実はjavascriptにバンドルしないなら必要というわけではないらしい。とりあえずいれた。
  • mini-css-extract-plugin・・・cssファイルをバンドルせず、別々のファイルで出力するときに使う。(結局バンドルしないのか、と思われるかもしれませんが、cssは個人的にはファイル分けたいです。)

とりあえずインストールするものは以上になります。

webpack.config.jsの設定をする。

次はwebpack.config.jsというファイルをルートディレクトリ直下に作成し、ビルドやトランスパイラの詳細な設定をつけていきます。

const path = require('path');//node.jsのpathモジュールを使えるようにしている
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const autoprefixer = require('autoprefixer');
process.env.NODE_ENV = 'production';//developmentかどちらか選ぶ

module.exports = {
    mode: 'production',//developmentかどちらか選ぶ
    entry: './src/index.js',//バンドルする起点となるjsファイルを選ぶ。
    output: {
      filename: 'main.js',//バンドルしたあとのファイル名
      path: path.resolve(__dirname, 'dist'),//ルートディレクトリから、distというフォルダの中にできる
    },
    module: {
      rules: [
        {
          test: /\.js$/,//正規表現でjsファイルにbabelを使っていくよという指定
          exclude: /node_modules/,//node_modulesにはbabel使わないという除外指定
          use: {
            loader: 'babel-loader',
            options: {
                presets: [
                    ['@babel/preset-env', {
                      targets: {//どのようなブラウザに対応させるか
                        browsers: ['last 3 version', 'not dead', 'iOS >= 12', 'Safari >= 14']
                      },
                      useBuiltIns: 'usage',//最低限のpolyfillを使うよという指定
                      corejs: 3
                    }]
                  ],
                  plugins: [
                    ['@babel/plugin-transform-runtime', { regenerator: true }],
                  ],
                },
              },
            },
        {
            test: /\.css$/i,
            use: [
              MiniCssExtractPlugin.loader,
              'css-loader',
              {
                loader: 'postcss-loader',
                options: {
                  postcssOptions: {
                    plugins: [
                      autoprefixer({
                        overrideBrowserslist: [//どのようなブラウザに対応させるか
                            'last 3 version',
                            'not dead',
                            'iOS >= 12',
                            'Safari >= 14'
                    ],
                      })
                    ],
                  },
                },
              },
            ],
          },
        ],
      },
      plugins: [
        new MiniCssExtractPlugin({
          filename: 'style.css',//cssファイルをこの名前で出力
        }),
      ],
    };

ここはただバンドルやトランスパイルの詳細な設定をしているだけです。どのローダーを使うか、プラグインを使うか設定して、optionなどで詳細を設定しています。中でもbabelとautoprefixerなどで、どのようなブラウザに対応したコードの変換をするかという設定があり、個人の好みというか、自分の好きなように設定していけばいいと思います。

基本的にはbrowserslistとしてbabel.config.jsやpackage.jsonの設定として新規作成したり追記するらしいのですが、うまくいかなかったのでwebpack.config.jsに書いてしまっています。

なのでbrowserslistとしてググってみると、対応ブラウザの設定について調べることができますので、詳細はそこから調べてみてください。自分は、以下のブログ記事を参照し同じように設定してみました。

webpackを実行する

今自分が設定しているのは、productionモードでの出力です。

srcフォルダを作る

ルートディレクトリの下にsrcフォルダを作り、そこにindex.html以外のファイルや画像を突っ込みます。このフォルダの中にある部品を見て、webpackは依存関係を整理してくれます。

今回はentryファイルとしてindex.jsと設定しているので、メインのjavascriptの名前をindex.jsとしておいてください。

distフォルダを作る

今度はdistフォルダを作り、index.htmlをいれておきます。今回はこのindex.htmlからcss, jsなどを読み込んでいきますので、出力されるファイルの名前できちんと読み込むように設定しておきます。

例えば、今回はmain.jsという名前で出力しようと思うので、

<script src="./main.js"></script>

こんな感じでちゃんと設定しておきます。

実行コマンド

package.jsonで作っておいたコマンドを使用します。

npm run build //development用
npm run prod //production用

development用に出力する場合は今まで設定していたproductionモードの設定を修正してから実行してください。

おわり

これで終わりなんですが、autoprefixerなどはもうほとんどついてない状態で出力されました。自分の場合あまり特殊なプロパティ使わないので、これなら何もしてないのと一緒じゃないか…?と若干残念な気持ちになりましたが、いつ対応していないコードを使うかわからないので、今回はここまでできて一応満足です。

でも今回は本当に最低限の設定しかしてないので、やっぱり難しいなと思いました。

コメント