摘要:原文譯者插件能夠?qū)⒁娴娜繚摿Ρ┞督o第三方的開發(fā)者。當(dāng)將一個插件應(yīng)用到環(huán)境中,這個插件將會獲得一個對于這個的引用。表示有關(guān)模塊資源,已編譯資源,已更改文件和監(jiān)視依賴關(guān)系的當(dāng)前狀態(tài)的信息。
原文:how to write a plugin
譯者:neal1991
welcome to star my articles-translator , providing you advanced articles translation. Any suggestion, please issue or contact me
LICENSE: MIT
插件能夠?qū)ebpack引擎的全部潛力暴露給第三方的開發(fā)者。通過使用階段構(gòu)建回調(diào),開發(fā)者能夠?qū)⑺麄冏约旱男袨橐氲絯ebpack的構(gòu)建過程中。構(gòu)建插件比構(gòu)建loader更高級,因為你需要理解一些webpack低層次的內(nèi)部鉤子。準備好閱讀一些源代碼吧!
Compiler以及Compilation在開發(fā)插件的時候最重要的兩個資源就是compiler和compilation對象。理解它們的角色是拓展webpack引擎重要的第一步。
compiler對象代表了完整的配置的webpack環(huán)境。一旦開啟webpack之后,這個對象就被構(gòu)建了,并且這個對象會使用所有操作設(shè)置,包括options, loaders, 以及plugins來進行配置。當(dāng)將一個插件應(yīng)用到webpack環(huán)境中,這個插件將會獲得一個對于這個compiler的引用。使用這個compiler可以訪問主要的webpack環(huán)境。
一個compilation對象代表版本資源的一次構(gòu)建。當(dāng)運行webpack開發(fā)中間件的時候,每次檢測到文件變化的時候都會產(chǎn)生一個新的compilation,因此會生成一系列編譯后的資源。Compilation表示有關(guān)模塊資源,已編譯資源,已更改文件和監(jiān)視依賴關(guān)系的當(dāng)前狀態(tài)的信息。該compilation還提供了許多回調(diào)點,插件可以選擇執(zhí)行自定義操作。
這兩個組件是任何webpack插件(特別是compilation)的內(nèi)部一部分,因此開發(fā)者熟悉這些源代碼文件之后將會受益非凡:
Compiler Source
Compilation Source
基本的插件架構(gòu)插件是實例對象,并且在它們的prototype上,會有一個apply方法。當(dāng)安裝這個插件的時候,這個apply方法就會被webpack compiler調(diào)用。這個apply會給出一個對于潛在的webpack compiler的引用,保證了對于compiler回調(diào)的訪問。一個簡單的插件結(jié)構(gòu)如下:
function HelloWorldPlugin(options) { // Setup the plugin instance with options... } HelloWorldPlugin.prototype.apply = function(compiler) { compiler.plugin("done", function() { console.log("Hello World!"); }); }; module.exports = HelloWorldPlugin;
接著是安裝這個插件,只要在你的webpack 配置plugins數(shù)組里面添加一個實例:
var HelloWorldPlugin = require("hello-world"); var webpackConfig = { // ... config settings here ... plugins: [ new HelloWorldPlugin({options: true}) ] };訪問compilation
使用compiler對象,你可能綁定提供那個對于每一個新的compilation引用的回調(diào)。這些compilation提供對于在構(gòu)建過程中對于很多步驟鉤子的回調(diào)。
function HelloCompilationPlugin(options) {} HelloCompilationPlugin.prototype.apply = function(compiler) { // Setup callback for accessing a compilation: compiler.plugin("compilation", function(compilation) { // Now setup callbacks for accessing compilation steps: compilation.plugin("optimize", function() { console.log("Assets are being optimized."); }); }); }; module.exports = HelloCompilationPlugin;
對于更多關(guān)于compiler以及compilation上的回調(diào)以及其他重要的對象,請參考 [[plugins API|plugins]] 文檔。
異步compilation plugins有一些compilation插件步驟是異步的,并且當(dāng)你的插件完成運行的時候,傳遞一個必須被調(diào)用的回調(diào)函數(shù)。
function HelloAsyncPlugin(options) {} HelloAsyncPlugin.prototype.apply = function(compiler) { compiler.plugin("emit", function(compilation, callback) { // Do something async... setTimeout(function() { console.log("Done with async work..."); callback(); }, 1000); }); }; module.exports = HelloAsyncPlugin;一個簡單的例子
一旦我們可以鎖定到webpack compiler以及每一個獨立的compilation,我們可以利用引擎本身就能發(fā)揮無窮的潛力。我們能夠重新格式化存在的文件,創(chuàng)建衍生文件,或者制造全新的資源。
讓我們寫一個簡單的能夠生成一個新的打包文件filelist.md的插件例子;這個文件的內(nèi)容會列出所有存在我們build之內(nèi)的資源文件。這個插件可能看起來是這個樣子的:
function FileListPlugin(options) {} FileListPlugin.prototype.apply = function(compiler) { compiler.plugin("emit", function(compilation, callback) { // Create a header string for the generated file: var filelist = "In this build: "; // Loop through all compiled assets, // adding a new line item for each filename. for (var filename in compilation.assets) { filelist += ("- "+ filename +" "); } // Insert this list into the Webpack build as a new file asset: compilation.assets["filelist.md"] = { source: function() { return filelist; }, size: function() { return filelist.length; } }; callback(); }); }; module.exports = FileListPlugin;有用的插件模式
插件允許在webpack構(gòu)建系統(tǒng)內(nèi)發(fā)揮無盡可能的定制化。這允許你創(chuàng)建自定義的資源類型,執(zhí)行特殊的構(gòu)建調(diào)整,或者設(shè)置在使用中間件的時候進一步提升webpack運行時間。下面的webpack的一些特性在開發(fā)插件的時候變得很有用。
探索assets, chunks, modules, 以及dependencies在compilation完成之后,compilation中的所有的結(jié)構(gòu)都可能被遍歷。
function MyPlugin() {} MyPlugin.prototype.apply = function(compiler) { compiler.plugin("emit", function(compilation, callback) { // Explore each chunk (build output): compilation.chunks.forEach(function(chunk) { // Explore each module within the chunk (built inputs): chunk.modules.forEach(function(module) { // Explore each source file path that was included into the module: module.fileDependencies.forEach(function(filepath) { // we"ve learned a lot about the source structure now... }); }); // Explore each asset filename generated by the chunk: chunk.files.forEach(function(filename) { // Get the asset source for each file generated by the chunk: var source = compilation.assets[filename].source(); }); }); callback(); }); }; module.exports = MyPlugin;
compilation.modules: 在compilation中由模塊(構(gòu)建輸入)組成的數(shù)組。每個模塊管理來自于源代碼庫中的源文件的構(gòu)建。
module.fileDependencies: 包含在模塊中的源文件路徑數(shù)組。 這包括源JavaScript文件本身(例如:index.js)以及所需的所有依賴項資源文件(樣式表,圖像等)。 查看依賴關(guān)系對于查看哪些源文件屬于模塊很有用。
compilation.chunks: Compilation中由chunks組成的數(shù)組(構(gòu)建輸出)。 每個chunk管理最終渲染資源的組合。
chunk.modules: 包含在一個chunk中的模塊數(shù)組。 通過擴展,您可以查看每個模塊的依賴關(guān)系,以查看傳遞到chunk中的原始源文件
chunk.files: 由chunk生成的輸出文件名的數(shù)組。 您可以從compilation.assets表訪問這些資源。
檢測觀察圖在運行webpack中間件時,每個compilation都包含一個fileDependencies數(shù)組(正在監(jiān)視的文件)和一個將觀察文件路徑映射到時間戳的fileTimestamps哈希。 這些對于檢測compilation中哪些文件已更改非常有用:
function MyPlugin() { this.startTime = Date.now(); this.prevTimestamps = {}; } MyPlugin.prototype.apply = function(compiler) { compiler.plugin("emit", function(compilation, callback) { var changedFiles = Object.keys(compilation.fileTimestamps).filter(function(watchfile) { return (this.prevTimestamps[watchfile] || this.startTime) < (compilation.fileTimestamps[watchfile] || Infinity); }.bind(this)); this.prevTimestamps = compilation.fileTimestamps; callback(); }.bind(this)); }; module.exports = MyPlugin;
您還可以將新的文件路徑傳入觀察圖,以便在這些文件更改時接收compilation觸發(fā)器。 只需將有效的文件路徑推送到compilation.fileDependencies數(shù)組中即可將其添加到觀察列表中。 注意:在每個compilation中重建fileDependencies數(shù)組,因此您的插件必須將自己觀察的依賴項推送到每個編譯中,以使它們保持監(jiān)視。
改變的chunks與觀察圖類似,通過跟蹤它們的哈希值,可以在compilation中監(jiān)視更改的塊(或模塊)。
function MyPlugin() { this.chunkVersions = {}; } MyPlugin.prototype.apply = function(compiler) { compiler.plugin("emit", function(compilation, callback) { var changedChunks = compilation.chunks.filter(function(chunk) { var oldVersion = this.chunkVersions[chunk.name]; this.chunkVersions[chunk.name] = chunk.hash; return chunk.hash !== oldVersion; }.bind(this)); callback(); }.bind(this)); }; module.exports = MyPlugin;
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/82989.html
摘要:有哪些新特性有哪些改進學(xué)著使用這個新版本,來構(gòu)建更快的應(yīng)用吧。繼版本之后,花了將近八個月的時間來發(fā)布。的創(chuàng)始人之一,,建議用戶使用,以便使用最優(yōu)的性能,是因為源代碼使用了新特性。全新的插件系統(tǒng)配備了全新整改的插件系統(tǒng)。 本文原文地址:https://auth0.com/blog/webpac...第一次翻譯,不當(dāng)之處,歡迎指正 官方已經(jīng)發(fā)布了Webpack 4.0。有哪些新特性?有哪些...
摘要:我們已經(jīng)運用了的一些閃亮的新特性,那么如何才能轉(zhuǎn)化為的代碼呢首先,我們需要通過來安裝在全局安裝會提供我們一個命令行工具。 你是不是也在為可以使用ES6的新特性而興奮,卻不太確定應(yīng)該從哪開始,或者如何開始?不止你一個人這樣!我已經(jīng)花了一年半的時間去解決這個幸福的難題。在這段時間里 JavaScript 工具鏈中有幾個令人興奮的突破。 這些突破讓我們可以用ES6書寫完全的JS模塊,而不會為...
摘要:相反,解釋背后的原理是什么使他比一個構(gòu)造器更加強大。仍然是構(gòu)造器類似這樣的工具存在的主要原因之一就是解決依賴問題。是一個模塊構(gòu)造器,就是前文所說的。 Webpack是一個JavaScript模塊構(gòu)造器。 這是適合它功能的名稱。 但是,我想在本文中展現(xiàn)Webpack的真正功能。 本文將不講解如何使用Webpack。 相反,解釋背后的原理:是什么使他比一個構(gòu)造器更加強大。 Webpack仍...
摘要:現(xiàn)在,讓我們創(chuàng)建項目的入口,并使用然后創(chuàng)建我們的配置,文件名為,的配置文件是一個,并且需要成一個對象在這里,告訴那些文件是你應(yīng)用的入口。代碼分割便是用來解決之前所說的單集成模塊不可維護的引用的問題。 構(gòu)建工具逐漸成為前端工程必備的工具,Grunt、Gulp、Fis、Webpack等等,譯者有幸使用過Fis、Gulp。前者是百度的集成化方案,提供了一整套前端構(gòu)建方案,優(yōu)點是基本幫你搞定了...
摘要:點擊直達前文譯一個小時搭建一個全棧應(yīng)用框架上如果沒有,但還是要繼續(xù)學(xué)習(xí)本教程,可以到我的頁面下載代碼。從服務(wù)器返回隨機語言的每當(dāng)我們與服務(wù)器上的端點進行通話時,為了能夠請求一個隨機的歐洲語言,必須更改文件中的功能。 翻譯:瘋狂的技術(shù)宅原文標(biāo)題:Creating a full-stack web application with Python, NPM, Webpack and Reac...
閱讀 3084·2023-04-26 00:53
閱讀 3534·2021-11-19 09:58
閱讀 1698·2021-09-29 09:35
閱讀 3287·2021-09-28 09:46
閱讀 3866·2021-09-22 15:38
閱讀 2696·2019-08-30 15:55
閱讀 3015·2019-08-23 14:10
閱讀 3829·2019-08-22 18:17