序文wabpack では、ローダーの他にプラグインがコア機能です。プラグインは、webpack の実行中に一連のイベントをブロードキャストします。プラグインはこれらのイベントをリッスンし、webpack API を介して出力ファイルを処理します。たとえば、hmlt-webpack-plugin はテンプレート index.html を dist ディレクトリにコピーします。 知るまずはソースコードを通してプラグインの基本構造を理解しましょう // コンパイラを作成する createChildCompiler( コンパイル、 コンパイラ名、 コンパイラインデックス、 出力オプション、 plugins // プラグインを含む) { // 新しいコンパイラ const childCompiler = new Compiler(this.context); // 既存のプラグインをすべて検索 if (Array.isArray(plugins)) { for (const plugin of plugins) { // 存在する場合は、プラグインの適用メソッドを呼び出します。plugin.apply(childCompiler); } } // プラグインに対応するフックをトラバースして見つける for (const name in this.hooks) { もし ( ![ "作る"、 "コンパイル"、 「放出」、 「afterEmit」、 "無効"、 "終わり"、 「このコンピレーション」 ].includes(名前) ){ // 対応するフックを見つけて呼び出します。 if (childCompiler.hooks[名前]) { childCompiler.hooks[名前].taps = this.hooks[名前].taps.slice(); } } } // .... 省略.... 子コンパイラを返します。 } 上記のソースコードから、プラグインは本質的にクラスであることがわかります。まず、コンパイラクラスが作成され、現在のコンテキストが渡され、それが存在するかどうかが判断されます。存在する場合は、対応するプラグインの apply メソッドが直接呼び出され、対応するプラグインによって呼び出されたフックイベントストリームが見つかり、対応するフックイベントに送信されます。 https://github.com/webpack/webpack/blob/webpack-4/lib/Compiler.js 42行目 // 上記の Compiler クラスは Tapable クラスを継承しており、Tapable はこれらのフック イベント フローを定義します。class Compiler extends Tapable { コンストラクタ(コンテキスト) { 素晴らしい(); this.hooks = { /** @type {SyncBailHook<コンパイル>} */ shouldEmit: 新しいSyncBailHook(["コンパイル"])、 /** @type {AsyncSeriesHook<Stats>} */ 完了: 新しい AsyncSeriesHook(["stats"])、 /** @type {AsyncSeriesHook<>} */ 追加パス: 新しいAsyncSeriesHook([])、 /** @type {AsyncSeriesHook<Compiler>} */ beforeRun: 新しいAsyncSeriesHook(["compiler"])、 /** @type {AsyncSeriesHook<Compiler>} */ 実行: 新しい AsyncSeriesHook(["compiler"]), /** @type {AsyncSeriesHook<コンパイル>} */ 出力: 新しい AsyncSeriesHook(["コンパイル"]), /** @type {AsyncSeriesHook<文字列、バッファ>} */ アセットが発行されました: 新しい AsyncSeriesHook(["file", "content"]), /** @type {AsyncSeriesHook<コンパイル>} */ afterEmit: 新しいAsyncSeriesHook(["コンパイル"])、 /** @type {SyncHook<Compilation, CompilationParams>} */ thisCompilation: 新しいSyncHook(["compilation", "params"]), /** @type {SyncHook<Compilation, CompilationParams>} */ コンパイル: 新しい SyncHook(["コンパイル", "パラメータ"]), /** @type {SyncHook<NormalModuleFactory>} */ normalModuleFactory: 新しいSyncHook(["normalModuleFactory"])、 /** @type {SyncHook<ContextModuleFactory>} */ contextModuleFactory: 新しいSyncHook(["contextModulefactory"])、 /** @type {AsyncSeriesHook<CompilationParams>} */ コンパイル前: 新しい AsyncSeriesHook(["params"])、 /** @type {SyncHook<CompilationParams>} */ コンパイル: 新しいSyncHook(["params"])、 /** @type {AsyncParallelHook<コンパイル>} */ 作成: 新しい AsyncParallelHook(["コンパイル"])、 /** @type {AsyncSeriesHook<コンパイル>} */ afterCompile: 新しいAsyncSeriesHook(["コンパイル"])、 /** @type {AsyncSeriesHook<Compiler>} */ watchRun: 新しいAsyncSeriesHook(["compiler"])、 /** @type {SyncHook<Error>} */ 失敗: 新しいSyncHook(["error"])、 /** @type {SyncHook<文字列, 文字列>} */ 無効: 新しいSyncHook(["filename", "changeTime"]), /** @type {SyncHook} */ watchClose: 新しいSyncHook([])、 /** @type {SyncBailHook<string, string, any[]>} */ インフラストラクチャログ: 新しい SyncBailHook(["origin", "type", "args"])、 // TODO 次のフックは奇妙な場所にここにあります // TODO webpack 5 用に移動します /** @type {SyncHook} */ 環境: 新しいSyncHook([])、 /** @type {SyncHook} */ afterEnvironment: 新しいSyncHook([])、 /** @type {SyncHook<コンパイラ>} */ afterPlugins: 新しいSyncHook(["compiler"])、 /** @type {SyncHook<コンパイラ>} */ afterResolvers: 新しいSyncHook(["compiler"])、 /** @type {SyncBailHook<文字列, エントリ>} */ エントリオプション: 新しい SyncBailHook(["context", "entry"]) }; // TODO webpack 5 これを削除する this.hooks.infrastructurelog = this.hooks.infrastructureLog; // 対応するコンパイラをタブで呼び出し、コールバック関数を渡します this._pluginCompat.tap("Compiler", options => { スイッチ (オプション.名前) { ケース「追加パス」: 「実行前」の場合: ケース「実行」: ケース「emit」: 「アフターエミット」の場合: 「コンパイル前」の場合: ケース「make」: 「コンパイル後」の場合: ケース「watch-run」: オプション。 壊す; } }); // 以下省略...... } さて、基本的な構造を理解した後、プラグインの基本的な構造と使用法を推測することができます。それは次のようになります。 // プラグインクラスを定義する class MyPlugins { // 前述のように、新しいコンパイラインスタンスが作成され、そのインスタンスのapplyメソッドが実行され、対応するコンパイラインスタンスが渡されます。apply (compiler) { // 新しいコンパイラインスタンスの下でフックイベントフローを呼び出し、タブを通じてそれをトリガーし、コールバック関数を受け取ります。compiler.hooks.done.tap('通常はプラグインのニックネーム'、(デフォルトの受信パラメータ) => { console.log('実行本体を入力してください'); }) } } // エクスポートモジュール.exports = MyPlugins 上記は単純なテンプレートです。内部フック関数を試して、期待どおりに呼び出されてトリガーされるかどうかを確認しましょう。 webpackを設定する path = require('path') とします。 DonePlugin = require('./plugins/DonePlugins') とします。 AsyncPlugins = require('./plugins/AsyncPlugins') とします。 モジュール.エクスポート = { モード: '開発'、 エントリ: './src/index.js', 出力: { ファイル名: 'build.js', パス: path.resolve(__dirname, 'dist') }, プラグイン: [ new DonePlugin(), // 内部同期フック new AsyncPlugins() // 内部非同期フック ] } 同期プラグイン プラグインシミュレーション呼び出し クラス DonePlugins { 適用(コンパイラ){ コンパイラーフックの完了.tap('DonePlugin', (統計) => { console.log('実行: コンパイルが完了しました'); }) } } module.exports = 完了プラグイン 非同期プラグイン プラグイン シミュレーション呼び出し クラスAsyncPlugins { 適用(コンパイラ){ コンパイラーフックのemit.tapAsync('AsyncPlugin', (complete, callback) => { タイムアウトを設定する(() => { console.log('実行: ファイルが出力されました'); 折り返し電話() }, 1000) }) } } module.exports = 非同期プラグイン 最後に、webpack をコンパイルすると、コンパイル コンソールが表示され、次のように出力されて実行されます: コンパイルが完了しました。実行: ファイルが発行され、フック イベント フローを呼び出してトリガーできることが示されます。 練習すれば完璧になる基本的な構造と使い方がわかったので、プラグインを書いてみましょう。ファイル記述プラグインを書いてみましょう。日常のパッケージングでは、xxx.md ファイルを dist ディレクトリにパッケージ化し、パッケージ記述を作成することで、このような小さな機能を実現できます。 ファイル説明プラグイン クラスFileListPlugin { // 初期化、ファイル名を取得するコンストラクタ ({filename}) { this.filename = ファイル名 } // 同じテンプレート形式で、apply メソッドを定義します。apply (compiler) { コンパイラー.フック.emit.tap('FileListPlugin', (コンパイル) => { // アセットは静的リソースであり、コンパイルパラメータを出力でき、多くのメソッドとプロパティがあります。let アセット = compilation.assets; // 出力ドキュメント構造を定義します let content = `## ファイル名 リソース サイズ\r\n` // 静的リソースを走査し、出力コンテンツを動的に結合します Object.entries(assets).forEach(([filename, stateObj]) => { コンテンツ += `- ${filename} ${stateObj.size()}\r\n` }) // 出力リソースオブジェクトassets[this.filename] = { ソース () { コンテンツを返します。 }, サイズ () { コンテンツの長さを返す } } }) } } // エクスポート module.exports = FileListPlugin webpack の設定 path = require('path') とします。 HtmlWebpackPlugin = require('html-webpack-plugin') を設定します。 // プラグインディレクトリは、node_modules、カスタムプラグインと同じレベルにあり、ローダーに似ています。let FileListPlugin = require('./plugins/FileListPlugin') モジュール.エクスポート = { モード: '開発'、 エントリ: './src/index.js', 出力: { ファイル名: 'build.js', パス: path.resolve(__dirname, 'dist') }, プラグイン: [ 新しいHtmlWebpackプラグイン({ テンプレート: './src/index.html', ファイル名: 'index.html' })、 新しいファイルリストプラグイン({ ファイル名: 'list.md' }) ] } 上記の設定により、再度パッケージ化すると、パッケージ化されるたびに dist ディレクトリに xxx.md ファイルが表示され、このファイルの内容が上記の内容になることがわかります。 Webpack4プラグインの実装原理に関するこの記事はこれで終わりです。Webpack4プラグインに関するその他の関連コンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: MySQLの比較演算子正規表現マッチングREGEXPの使用の詳細な説明
この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...
目次DOMContentLoadedとロードjs ブロッキングとは何ですか? CSS ブロッキングと...
1. <body background=画像ファイル名 bgcolor=color text=...
pthread_create関数機能紹介pthread_createはUNIX環境のスレッド作成関数...
目次インストール手順環境設定実行構成インストール手順ダウンロードアドレス: バージョン6.0 最初に...
1. CPU使用率sar -p (一日中表示) sar -u 1 10 (1: 1秒ごと、10: 1...
まずは違いについて話しましょう最後に、書き換えられたルールは、次の場所と一致させるために書き換えられ...
Java開発キットjdkをダウンロードするJDK のダウンロード アドレスはhttp://www.o...
目次序文ベジェ曲線の紹介二次ベジェ曲線3次ベジェ曲線ベジェ曲線計算機能フィッティングアルゴリズム付録...
実際のプロジェクトでは、複数のテーブル間に関係が存在します。 1 つのテーブル内のすべてのデータを取...
目次1. 基本的な使い方2. 画像量の制御3. 画像形式の制限/複数の画像を選択可能補足: vueプ...
目次質問1: 小道具は具体的にどのように使用されますか?原理は何ですか?下を見る質問 2: 年齢に ...
1. 動作環境vmware14proウブントゥ 16.04LTS 2. 問題の説明vmware14P...
DOCTYPE が次のとおりである場合:コードをコピーコードは次のとおりです。 <!DOCTY...
目次mysql マスタースレーブレプリケーションMySQL マスタースレーブレプリケーション方式My...