matsutoba’s blog

フロントエンドエンジニアをしています

webpackの覚書

なんとなく使ってしまっているwebpackeについて、よく使うところの覚書。

webPackとは

webpackでできること

* コンテンツを構成するファイルを1つにまとめる。
* 複数のファイルを1つにまとめることで、ブラウザでコンテンツを表示するときのファイル転送が1度で済む。

モジュール方式とは

モジュール

* 機能ごとに分割されたJavaScriptファイルのこと
* モジュール読み込み仕様として主要なものはCommonJS ModulesとECMAScript Modules

CommonJS Modules (CJS)

* モジュールでは module.exports で関数を定義し、読み込み側では require で読み込む。

// モジュール定義側 sub.js
module.exports = function() {
    console.log('cjs module');
}
// モジュール読み込み側
const subModule = require('./sub.js');
subModule();
ECMAScript Modules (ESM)

* ES6で定義された仕様で、モジュール側ではexportで関数を定義し、読み込み側ではimportで読み込む。

// モジュール定義側 sub.js
export const moduleFunc = function() {
    console.log('esm module');
}
// モジュール読み込み側
import { moduleFunc } from './sub'
moduleFunc();

webpackのインストール

以下のコマンドを実行する。

npm install -D webpack webpack-cli

webpack4以降では設定ファイルがなくてもデフォルト動作で実行できる。

npx webpack

これにより、/dist フォルダに main.js ファイルが生成される。

コマンドのカスタマイズ

npm scriptsを使ってpackage.jsonにコマンドのショートカットを記述することで、webpackのビルドコマンドを追加できる。

初期状態のpackage.json

npm init -y コマンド実行直後に作成されるpackage.jsonはこのようになっている。

{
  "name": "myproject",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1"
  }
}

ここから最低限必要な部分だけ残すとこうなる。

  "scripts": {},
  "devDependencies": {
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1"
  }

ビルドコマンドの追加

script部分にbuildコマンドを追加するとこうなる。

  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^5.75.0",
    "webpack-cli": "^5.0.1"
  }

buildコマンドを実行する場合は

npm run build

webpackの動作のカスタマイズ

設定ファイル

package.jsonと同じ階層にwebpack.config.jsファイルを作成し、このファイルにwebpackの動作を指定することができる。

エントリポイントの指定

webpack.config.jsでentryを指定する。

module.exports = {
  // entryを指定しなければ src/index.js がエントリーポイントになる
  // ドットから始まる相対パスか、${__dirname}を使用した絶対パスで指定
  entry: './src/index.js'
}

出力先の指定

webpack.config.jsでoutputを指定する。

module.exports = {
  // outputを指定しなければ dist/main.js が出力ファイルになる
  output: {
    // 出力先フォルダは絶対パスで指定(存在しないフォルダの場合は自動的に作成される)
    path: `${__dirname}/dist`,
    // ファイル名
    filename: 'main.js',
},
メモ:パスの指定について

webpack.config.js中にパスを指定する場合、path.joinを使ったほうが良さそう。
パスの区切り文字を適切に扱ってくれるため。
ただし、"./" から始まるパスの場合は文字列として指定する必要がある。

const path = require('path')

module.exports = {
  entry: `./src/index.js`,
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'main.js',
  },
}

ソースマップ(変換されたコードと元コードのマッピング

webpack.config.jsでmodeをdevelopmentとして指定する。

module.exports = {
  // development にするとソースマップが有効になる
  mode: "development"
};

デバッグ用のmapファイル生成

devtoolを指定すると、webpack実行時にmain.js.mapというmapファイルも作成される。このファイルがあるとchromeなどのブラウザで元ソースを使ってデバッグできるようになる。
devtoolに指定する値はこちらから確認。

module.exports = {
  devtool: "source-map"
};

環境別のwebpack動作設定

環境別のwebpack.config.jsの作成

開発用と本番用で別のファイルを作成しておく。
* webpack.dev.config.js
* webpack.prod.config.js

ビルドコマンドを環境別に分ける

package.jsonのscriptsに環境別のコマンドを用意し、webpackコマンドのオプションで環境別の設定ファイルを指定する。

  "scripts": {
    "build-dev": "webpack --config webpack.dev.config.js"
    "build-prod": "webpack --config webpack.prod.config.js"
  },