45
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ラクス Advent Calendar 2016 の12日目の記事です。
昨日は @AkiraTamai さんによる「 Erlangで1プロセス作成するのに必要な時間を計ってみた 」でした。

Advent Calendarの日取りを失敗してしまい、うっかりベトナム旅行中から投稿している @bakunyo@github です :sweat_smile:

webpack とは

突然ですが皆さん webpack 使ってますか?
まだ知らない、使ったことが無いという方は以下の記事をご参考ください。
webpack で始めるイマドキのフロントエンド開発

webpack はざっくりいうと、 JavaScriptモジュールの依存関係を解決しつつ、静的アセットを生成してくれるビルドツール です。
公式サイトに載っている以下の図がイメージしやすいです。

image

webpack plugin とは

webpack にはプラグイン機能があり、プラグインを追加することで ビルド実行時に様々な処理を追加する ことができます。
例えば UglifyJsPlugin は、アセット生成時に UglifyJs を使ってJavaScriptを圧縮してくれます。

ビルトインで提供されているプラグインも多く、以下はその一覧です。
LIST OF PLUGINS

webpack plugin のつくりかた

ここからが本題です。
ビルトイン以外にも多くのプラグインが公開されているように、プラグインは自作することができます

webpack ビルド処理の様々な箇所に処理を挿し込むことが可能です。
詳細は Plugins API に書かれていますが、 CompilerCompilation に紐付くイベントが大半です。

webpack plugin は、 compiler を引数として受け取る apply メソッドを持つオブジェクトです。
compilercompilationTapable を継承していて、 Plugins API に記載されている各所に処理を追加することができます。
処理を追加するには、 plugin メソッドにイベント名とハンドラー関数を渡して、その中に処理を書きます。

言葉ではなかなか伝えづらいので、サンプルコードを用意しました。

class MyWebpackPlugin {
  // compiler を引数として受け取る apply メソッド
  apply(compiler) {
    // plugin メソッドにイベント名とハンドラー関数を渡す
    compiler.plugin('compile', (params) => {
      console.log('compile開始時の処理');
    });

    compiler.plugin('compilation', (compilation, params) => {
      // compilation もまた plugin メソッドを持つので、各イベントに処理を追加できる
      compilation.plugin('optimize', () => {
        console.log('optimize(最適化)開始時の処理');
      });
    });

    // 非同期に実行されるイベントは callback を引数で受取り、適宜実行する
    compiler.plugin('emit', (compilation, callback) => {
      console.log('emit(アセット出力)開始時の処理');
      callback();
    });
  }
}

// webpack.config.js
module.exports = {
  entry: {
    // ... 
    // ... webpackの各種設定 ...
    // ... 
  },
  plugins: [
    new MyWebpackPlugin()
  ]  
}

上記のサンプルコードを実行した結果、出力は以下のようになりました。
webpack 実行時に、 plugin で追加した処理を通っていることが確認できます。

webpack.gif

webpack plugin の開発

サンプルコードで記載している通り、プラグイン開発時には CompilerCompilation などのオブジェクト、ハンドラー関数で受け取る引数などを扱う必要が出てきます。
そこで欲しくなるのが デバッグツール です。

今回はデバッグツールとして V8 Inspector をご紹介します。
こちらは Node.js に標準で入っており、 Chrome DevTools と連携するため導入はかなり楽です。

Node.js の古いバージョンだと入っていないかもしれません。
その場合はアップデートするか、 node-inspectornode-nightly で代用するなどを検討してみてください。

以下、使い方です。

下準備

処理を止めたい場所に debugger; と書きます。
今回は、サンプルコードの apply の直後に追加してみます。

class MyWebpackPlugin {
  apply(compiler) {
    debugger;            // ← ここに追加
    compiler.plugin('compile', (params) => {

デバッグ実行

以下のコマンドを実行します。
webpack は node_modules 配下にインストールしている想定です。

$ node --inspect --debug-brk node_modules/webpack/bin/webpack.js

実行している様子を以下に貼付けます。

inspector.gif

  • コマンド実行
  • 出力されたURLをChromeで開く
  • あとは通常の Chrome DevTools を使っている感じ

慣れ親しんだUIでデバッグできるので、とても楽です!

webpack についての補足

現在 webpack バージョン2がβ版として公開されています。
公式サイトも分かれているようです。
webpack.js.org

見たところ plugin の機能は引き続き残ります。
多少の設定変更が必要になることはあっても、大きくは変わらないようです。

参考

所感

今回の ラクス Advent Calendar 2016 を企画・運営してくれた @oohira さんありがとうございました!
数年前ではこういう企画が成り立つなんてなかなか考えられなかったことなので、感慨深いです。
今後も、こういったオープンな活動に積極的に取り組んでいけたらなと思います :smile:

45
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?