Webpackプラグインを書いてnpmに公開するための80行のコード

Webpackプラグインを書いてnpmに公開するための80行のコード

1. はじめに

最近、 Webpackの原理を勉強しています。これまでは Webpack の設定方法しか知りませんでしたが、内部のプロセスについては知りませんでした。一通り勉強した後、多くの恩恵を受けたと感じています。学んだことを定着させるために、自分でプラグインを書いてみることにしました。

このプラグインによって実装される関数は比較的単純です。

  • デフォルトでは、 jsコード内のconsole.logの印刷出力はクリアされます。
  • console.warnconsole.errorなど、 consoleを削除する他の方法は、構成を渡すことによって実装できます。

2. Webpackの構築プロセスとプラグインの原理

2.1 Webpackのビルドプロセス

Webpackの主な構築プロセスは、次の 3 つの段階に分けられます。

  • 初期化フェーズ: ビルドを開始し、構成パラメータを読み取ってマージし、 Pluginをロードし、 Compilerをインスタンス化します。
  • コンパイル フェーズ: Entryから発行され、各Moduleに対して対応するLoaderが順番に呼び出されてファイルの内容を変換し、次にModuleが依存するModuleが見つかり、再帰的にコンパイルされます。
  • 生成フェーズ: コンパイルされたModuleChunkに結合し、 Chunkファイルに変換して、ファイル システムに出力します。

Webpack本番環境ファイルをパッケージ化する場合、ビルドは 1 回だけ実行され、上記のステージが順番に実行されます。ただし、開発環境などで監視モードがオンになっている場合は、Webpack はビルドを続行します。

2.2 プラグインの原則

Webpackプラグインは通常、 apply関数を持つクラスであり、 constructor渡された構成項目を受け取ることができます。プラグインがインストールされると、 apply関数が 1 回呼び出され、 Compilerオブジェクトを受け取ります。その後、 Compilerオブジェクトでさまざまなイベント フックをリッスンして、プラグインの機能を開発できます。

// プラグインクラスを定義する MyPlugin {
  // プラグイン設定オプションを受け取るコンストラクタ 
  コンストラクタ(オプション) {
    // 設定項目を取得し、プラグインを初期化します}

  // プラグインがインストールされると、applyが呼び出され、コンパイラに渡されます
  適用(コンパイラ) {
    // comolier への排他的アクセスを取得し、イベント フックをリッスンできます // 関数開発... 
  }
}

2.3 コンパイラとコンパイルオブジェクト

Pluginの開発で最もよく使用される 2 つのオブジェクトは、 CompilerCompilationです。

  • Compilerオブジェクトは、 Webpackの起動時にインスタンス化されます。このオブジェクトには、 optionsloaderspluginsなど、 Webpack環境のすべての構成情報が含まれています。 Webpackビルド プロセス全体において、 Compilerオブジェクトはグローバルに一意であり、プラグインが使用できるイベント フック コールバックを多数提供します。
  • Compilationオブジェクトには、現在のモジュール リソース、コンパイルされたリソース、変更されたファイルなどが含まれます。 Compilationオブジェクトは、 Webpackビルド プロセスでは一意ではありません。Webpack Webpack開発モードでファイル検出機能をオンにすると、ファイルが変更されるたびにWebpackが再構築され、新しいCompilationオブジェクトが生成されます。 Compilationオブジェクトは、プラグインが拡張するためのイベント コールバックも多数提供します。

3. プラグイン開発

3.1 プロジェクトディレクトリ

このプラグインによって実装される機能は比較的単純であり、ファイル ディレクトリも複雑ではありません。まず、空のフォルダーremove-console-Webpack-pluginを作成し、フォルダー ディレクトリでnpm initを実行します。プロンプトに従って、 package.json関連情報を入力します。次に、新しいsrcフォルダーを作成し、プラグインのメイン コードをsrc/index.jsに配置します。プロジェクトをgithubに置く必要がある場合は、 .gitignoreREADME.mdなどのファイルを追加するのが最適です。

// コンソール Webpack プラグインを削除する
├─ソース
│ └─index.js  
├─.gitignore
├─package.json
└─README.md

3.2 プラグインコード

プラグイン コードのロジックは複雑ではありませんが、いくつかの主要なポイントがあります。

  • コンストラクターで構成パラメーターを受け取り、パラメーターをマージし、クリアする必要があるconsole関数を取得して、 removed配列に格納します。
  • apply関数で、 compiler.hook.compilationフックを listen します。フックがトリガーされた後、 compilationを取得し、さらにそのフックを listen します。Webpack4 とWebpack4 Webpack5フックはここで異なるため、互換性が必要です。
  • jsファイルを処理するためのassetsHandlerメソッドを定義し、正規表現を使用してremovedに含まれるconsole関数をクリアします。
クラス RemoveConsoleWebpackPlugin {
  // コンストラクタは設定パラメータを受け入れます。constructor(options) {
    include = options && options.include; とします。
    let removed = ['log']; // デフォルトのクリア方法if (include) {
      Array.isArray(include) の場合 {
        console.error('options.include は配列でなければなりません。');
      } そうでない場合 (include.includes('*')) {
        // * を渡すとすべてのコンソールがクリアされます removed = Object.keys(console).filter(fn => {
          戻り値の型は console[fn] === 'function' です。
        })
      } それ以外 {
        removed = include; // 受信した設定に従って上書きします}
    }

    this.removed = 削除されました;
  }

  // Webpack はプラグインインスタンスの apply メソッドを呼び出し、コンパイラオブジェクトを渡します。apply(compiler) {
    // js リソースコード処理関数 let assetHandler = (assets, compilation) => {
      removedStr を this.removed.reduce((a, b) => (a + '|' + b)); とします。

      reDict = {
        1: [正規表現(`\\.console\\.(${removedStr})\\(\\)`, 'g'), ''],
        2: [RegExp(`\\.console\\.(${removedStr})\\(`, 'g'), ';('],
        3: [RegExp(`console\\.(${removedStr})\\(\\)`, 'g'), ''],
        4: [RegExp(`console\\.(${removedStr})\\(`, 'g'), '(']
      }

      Object.entries(assets).forEach(([ファイル名, ソース]) => {
        // jsファイルに一致 if (/\.js$/.test(filename)) {
          // 処理前のファイルの内容 let outputContent = source.source();

          Object.keys(reDict).forEach(i => {
            [re, s] = reDict[i]とします。
            出力コンテンツ = outputContent.replace(re, s);
          })

          compilation.assets[ファイル名] = {
            // ファイルコンテンツソースを返す: () => {
              出力コンテンツを返す
            },
            // ファイルサイズを返す size: () => {
              Buffer.byteLength(outputContent, 'utf8') を返します。
            }
          }
        }
      })
    }

    /**
     *compiler.hooks.compilation.tapを通じてイベントをリッスンする *コールバックメソッドでコンパイルオブジェクトを取得する */
    コンパイラーフック.コンパイル.タップ('RemoveConsoleWebpackPlugin',
      コンパイル => {
        // ウェブパック5
        コンパイルフックのプロセスアセットの場合
          コンパイルフック.processAssets.tap(
            { 名前: 'RemoveConsoleWebpackPlugin' },
            アセット => アセットハンドラー(アセット、コンパイル)
          );
        } そうでない場合 (compilation.hooks.optimizeAssets) {
          // ウェブパック4
          コンパイルフックの最適化アセットのタップ(
            'RemoveConsoleWebpackPlugin', 
            アセット => アセットハンドラー(アセット、コンパイル)
          );
        }
      })
  }
}

// プラグインをエクスポート
module.exports = RemoveConsoleWebpackPlugin;

4. npmに公開する

他の人にプラグインを使ってもらいたい場合は、 npmに公開する必要があります。公開の主なプロセスは次のとおりです。

まず、 npm公式 Web サイトでアカウントを登録し、コマンドライン ツールを開いて、任意のディレクトリでnpm loginと入力し、プロンプトに従ってログインします。

ログイン後、 npm whoamiを使用してログインが成功したかどうかを確認できます。

公開する前に、ルート ディレクトリのpackage.jsonファイルが正しく入力されているかどうかを確認します。主なフィールドは次のとおりです。

  • name: ユーザーがプラグインをダウンロードするときに使用する名前を決定しますnpm上の既存のサードパーティ パッケージと同じ名前を付けることはできません。同じ名前にすると公開できません。
  • main: プラグインのメイン ファイル エントリ。Webpack Webpackプラグインを導入するときに、このディレクトリからインポートされます。
  • バージョン: アップデートがリリースされるたびに、バージョン番号が以前のバージョンと異なる必要があります。そうでない場合、アップロードは失敗します。
  • リポジトリ: プラグインのコードがgithubgitee 、またはその他の Web サイトに配置されている場合は、それを入力できます。
  • private: trueに設定することはできません。そうしないと公開できません。

すべての準備ができたら、プラグインが配置されているディレクトリに切り替えて、 npm publishを実行してプラグインをアップロードします。

アップロードに成功したら、 npm公式 Web サイトでプラグインが見つかるかどうか検索します。

5. 結論

これで、80行のコードでWebpackプラグインを書いてnpmに公開する記事は終了です。Webpackプラグインをnpmに公開する方法の詳細については、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Electron-vueはwebpackを使用して複数ページのエントリファイルをパッケージ化します
  • webpackコード断片化の実装
  • Webpack プロジェクトでローダー プラグインをデバッグする方法
  • Webpackを使用して複数ページのプログラムを構築するための実装手順
  • Webpack コンポーネントの使用状況統計を実装するための 50 行のコード
  • webpack -v エラー解決

<<:  Windows 10にOdoo12開発環境をインストールする方法

>>:  Linux での NVIDIA GPU 使用状況の監視の詳細な説明

推薦する

Linuxカーネルスケジューラソースコード初期化の分析

目次1. はじめに2. スケジューラの基本概念2.1. 実行キュー (rq) 2.2 スケジューリン...

Linux スワップ パーティション (詳細説明)

目次リナックス1. SWAPとは2. swappiness は何を調節しますか? 3. スワップ操作...

文字列の最初の文字を取得してテキストアイコン機能を実現する純粋なCSS

CSS でテキストアイコンを実装する方法 /*アイコンスタイル*/ .nav-icon-norma...

CSSでフォントアイコンを使用する方法をお教えします

まず、フォントアイコンとは何でしょうか?表面的にはアイコンですが、実際はテキストです。テキストの設定...

グループ化されたクエリでのGROUP BYの使用とSQL実行順序の説明

SQL では、GROUP BY は SELECT の結果のデータをグループ化するために使用されます。...

canvas.toDataURL image/png エラー処理方法の推奨

問題の背景:再生中のビデオのスクリーンショットを撮る必要があります。ビデオはビデオタグを使用して再生...

MySQL 学習のまとめ: InnoDB ストレージ エンジンのアーキテクチャ設計の予備的な理解

1. ストレージエンジン前のセクションでは、SQL 実行プランは、エグゼキュータ コンポーネントがス...

CSS3 は本当に SCSS に取って代わるのでしょうか?

Web ページのスタイル設定に関しては、プロジェクトで純粋な CSS または SCSS (および他...

React はモバイル端末を構築するために antd-mobile+postcss を導入しました

antd-mobileをインストールするグローバル輸入 npm をインストール antd-mobil...

Ubuntu で FTP サーバーを構築する方法の詳細な説明 (成功保証)

1. 今日の午後、コースの要件により、Ubuntu で FTP サーバーを設定する実験を行う必要が...

Kali に docker と portainer をインストールする方法

dockerの登場により、多くのサービスが徐々にハードウェアアーキテクチャへの依存から脱却しました。...

HTML でナンバープレート番号と州の略語を入力するためのサンプルコード

原理としては、まずボタン付きの div を記述し、次に画面のサイズに応じて自動的に適応してキーボード...

Linux で killall コマンドを使用してプロセスを終了する 8 つの例

Linux コマンドラインには、プロセスを強制終了するためのコマンドが多数用意されています。たとえば...

Vueコンポーネントの再利用と拡張の詳細な説明

目次概要延長は必要ですか?スロットJavaScript ユーティリティ関数拡張コンポーネントの複数の...

docker createコマンドの使用方法

docker create コマンドは、イメージに基づいてコンテナを作成できます。このコマンドの効果...