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

推薦する

Nginx で 403 forbidden を解決するための完全な手順

ウェブページに403 Forbiddenと表示されるNginx (yum インストール ログは通常 ...

HTMLのセマンティクスといくつかの簡単な最適化についての簡単な説明

1. セマンティゼーションとは何ですか? Bing辞書の説明セマンティクス化とは、適切な HTML ...

Vue.js プロジェクトの開始方法

目次1. Node.jsとVue 2. ローカル開発環境でフロントエンドのVueプロジェクトを実行す...

JavaScript BOM の説明

目次1. BOMの紹介1. JavaScriptは3つの部分から構成される2.ウィンドウオブジェクト...

Mysql の大きな SQL ファイルの高速リカバリ ソリューションの共有

序文MySQL データベースを使用する過程では、データベースのバックアップと復元が必要になることがよ...

CSSブロッキングマージとその他の効果についての簡単な説明

非直交マージンマージンを使用するとマージが発生します次のプロパティはマージンの結合を防止します。国境...

Workbench を介して MySQL データベースにリモートでアクセスする方法の詳細な説明

序文Workbench が 1 台のコンピューターにインストールされており、別の Ubuntu サー...

簡単な計算機を実装する小さなプログラム

この記事の例では、簡単な計算機を実装するための小さなプログラムの具体的なコードを参考までに共有してい...

CD コマンドを使わずに Linux でディレクトリ/フォルダに入る方法

ご存知のとおり、cd コマンドがないと、Linux でディレクトリを切り替えることはできません。それ...

CSS 位置固定左と右の二重配置実装コード

CSS 位置position 属性は、要素の配置タイプを指定します。位置プロパティには 5 つの値が...

Ubuntu インストール時にブラックスクリーンが表示される場合の解決策 (3 種類)

私のコンピューターのグラフィック カードは Nvidia グラフィック カードです。再起動後、画面に...

サブセットかどうかを判断するためのMySQLメソッドの手順

目次1. 問題2. 解決策オプション1:オプション2: 1. 問題この話は、エラーと脱落率を照会する...

露滴アニメーション効果を実装するための Three.js サンプル コード

序文みなさんこんにちは。CSS ウィザードの alphardex です。この記事では、three.j...

Linux 上の MySQL 5.7 でパスワードを忘れる問題を解決する

1. 問題Linux 上の mysql5.7 のパスワードを忘れました2. 解決策• ステップ 1:...