序文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の使用の詳細な説明
DIV+css構造 CSSレイアウトを学んでいますか?まだ純粋な CSS レイアウトを完全に習得でき...
Nginx のインストールCentOS 6.x yum にはデフォルトで nginx ソフトウェア ...
序文ストレス テスト中に、リソース使用のボトルネックによって発生する最も直接的なパフォーマンスの問題...
この記事では、ツリー構造テーブルを実現するためのElement-uiテーブルの具体的なコードを参考ま...
JavaScriptは、参考のためにランダムな点呼Webページを作成します。具体的な内容は次のとお...
カーソル選択クエリによって返される行のセットは、結果セットと呼ばれます。結果セット内の行は、入力した...
HTML5 では、入力用のネイティブ プレースホルダー属性が追加されており、これは高度なブラウザでサ...
問題の説明データ転送に Nginx を使用し、フロントエンドとバックエンドが分離された Spring...
目次Node.jsとはNodeJSをインストールするNode を使用して Hello World を...
圧縮アップロード画像、スクラッチカード、ポスター作成、チャートプラグインなど、フロントエンド開発にお...
この記事の例では、ページング効果表示を実現するためのミニプログラムの具体的なコードを参考までに共有し...
この記事では、スクロールウィンドウを実装するためのJavaScriptの具体的なコードを参考までに紹...
問題を見つける最近、仕事で問題が発生しました。MySQL データベースにテーブルを作成するときに、ラ...
序文WeChat アプレット開発 (ネイティブ wxml、wxcss) で、{{ }} 内で直接メソ...
ページレイアウトは、Web ページを扱い始めた頃からずっと気にかけていたことです。初期のテーブル構造...