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 使用状況の監視の詳細な説明

推薦する

MySQL 8.0.15 で MGR シングル マスターと複数スレーブを構成する方法

1. はじめにMySQL グループ レプリケーション (略して MGR) は文字通り MySQL グ...

Expressを使用してプロジェクトを自動的にビルドするNode.jsのプロセス全体

1. Expressライブラリとジェネレータをインストールするcmdを開いて、次のコマンドを入力しま...

埋め込みJavaScriptと外部リンクの基本的な応用方法

目次埋め込みJavaScriptと外部リンクの基本的な応用JavaScript の記述方法には、イン...

Vue でのカスタムディレクティブの基本的な使用方法

目次序文文章1. グローバル登録2. 部分登録3. フック機能とパラメータ設定4. 柔軟な使い方(1...

DockerはMysql、.Net6、Sqlserverなどのコンテナをデプロイします

目次CentOS 8にDockerをインストールする1. yumを更新する2. containerd...

Vueは単純なランダムロールコールを実行します

目次レイアウト部分: <div id="アプリ"> <p>...

私が遭遇したIE8の互換性に関する注意事項

1. IE8 の getElementById は id のみをサポートし、name はサポートしま...

Vue における属性とプロパティの具体的な使用法と違い

目次Vue.jsにおける属性とプロパティ値および関連する処理として属性とプロパティの概念属性とプロパ...

ユニアプリプロジェクトでのウォーターフォールレイアウトの実装

GitHubアドレス、気に入ったらスターを付けてくださいプラグインのプレビューチュートリアル1. プ...

Windowsタイムサーバーの設定方法の詳しい説明

最近、会社のサーバーの時間が不正確で、外部の時間ソースと同期できないことがわかりました。会社はドメイ...

Chrome Dev Tools を使用してページのパフォーマンスを分析する方法 (フロントエンドのパフォーマンス最適化)

背景開発やデバッグには Chrome Dev Tools がよく使用されますが、ページのパフォーマン...

Ubuntu での CUDA と CUDNN のインストールとアンインストールの実装

目次序文グラフィックドライバーをインストールするCUDAをアンインストールするCUDAをインストール...

HTMLはシンプルで美しいログインページを作成します

まずは見てみましょう。 HTML ソースコード: XML/HTML コードコンテンツをクリップボード...

SSL で Nginx リバース プロキシを構成する簡単な手順

序文リバース プロキシは、Web 経由で行われたリクエスト (http と https の両方) を...

MySQLフィルタリングレプリケーションのアイデアの詳細な説明

目次mysql フィルター レプリケーションメインデータベースに実装ライブラリから実装いくつかの質問...