成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯]如何寫一個(gè)webpack插件

wupengyu / 2003人閱讀

摘要:原文譯者插件能夠?qū)⒁娴娜繚摿Ρ┞督o第三方的開發(fā)者。當(dāng)將一個(gè)插件應(yīng)用到環(huán)境中,這個(gè)插件將會(huì)獲得一個(gè)對(duì)于這個(gè)的引用。表示有關(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更高級(jí),因?yàn)槟阈枰斫庖恍﹚ebpack低層次的內(nèi)部鉤子。準(zhǔn)備好閱讀一些源代碼吧!

Compiler以及Compilation

在開發(fā)插件的時(shí)候最重要的兩個(gè)資源就是compilercompilation對(duì)象。理解它們的角色是拓展webpack引擎重要的第一步。

compiler對(duì)象代表了完整的配置的webpack環(huán)境。一旦開啟webpack之后,這個(gè)對(duì)象就被構(gòu)建了,并且這個(gè)對(duì)象會(huì)使用所有操作設(shè)置,包括options, loaders, 以及plugins來進(jìn)行配置。當(dāng)將一個(gè)插件應(yīng)用到webpack環(huán)境中,這個(gè)插件將會(huì)獲得一個(gè)對(duì)于這個(gè)compiler的引用。使用這個(gè)compiler可以訪問主要的webpack環(huán)境。

一個(gè)compilation對(duì)象代表版本資源的一次構(gòu)建。當(dāng)運(yùn)行webpack開發(fā)中間件的時(shí)候,每次檢測(cè)到文件變化的時(shí)候都會(huì)產(chǎn)生一個(gè)新的compilation,因此會(huì)生成一系列編譯后的資源。Compilation表示有關(guān)模塊資源,已編譯資源,已更改文件和監(jiān)視依賴關(guān)系的當(dāng)前狀態(tài)的信息。該compilation還提供了許多回調(diào)點(diǎn),插件可以選擇執(zhí)行自定義操作。

這兩個(gè)組件是任何webpack插件(特別是compilation)的內(nèi)部一部分,因此開發(fā)者熟悉這些源代碼文件之后將會(huì)受益非凡:

Compiler Source

Compilation Source

基本的插件架構(gòu)

插件是實(shí)例對(duì)象,并且在它們的prototype上,會(huì)有一個(gè)apply方法。當(dāng)安裝這個(gè)插件的時(shí)候,這個(gè)apply方法就會(huì)被webpack compiler調(diào)用。這個(gè)apply會(huì)給出一個(gè)對(duì)于潛在的webpack compiler的引用,保證了對(duì)于compiler回調(diào)的訪問。一個(gè)簡(jiǎn)單的插件結(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;

接著是安裝這個(gè)插件,只要在你的webpack 配置plugins數(shù)組里面添加一個(gè)實(shí)例:

var HelloWorldPlugin = require("hello-world");

var webpackConfig = {
  // ... config settings here ...
  plugins: [
    new HelloWorldPlugin({options: true})
  ]
};
訪問compilation

使用compiler對(duì)象,你可能綁定提供那個(gè)對(duì)于每一個(gè)新的compilation引用的回調(diào)。這些compilation提供對(duì)于在構(gòu)建過程中對(duì)于很多步驟鉤子的回調(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;

對(duì)于更多關(guān)于compiler以及compilation上的回調(diào)以及其他重要的對(duì)象,請(qǐng)參考 [[plugins API|plugins]] 文檔。

異步compilation plugins

有一些compilation插件步驟是異步的,并且當(dāng)你的插件完成運(yùn)行的時(shí)候,傳遞一個(gè)必須被調(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;
一個(gè)簡(jiǎn)單的例子

一旦我們可以鎖定到webpack compiler以及每一個(gè)獨(dú)立的compilation,我們可以利用引擎本身就能發(fā)揮無窮的潛力。我們能夠重新格式化存在的文件,創(chuàng)建衍生文件,或者制造全新的資源。

讓我們寫一個(gè)簡(jiǎn)單的能夠生成一個(gè)新的打包文件filelist.md的插件例子;這個(gè)文件的內(nèi)容會(huì)列出所有存在我們build之內(nèi)的資源文件。這個(gè)插件可能看起來是這個(gè)樣子的:

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è)置在使用中間件的時(shí)候進(jìn)一步提升webpack運(yùn)行時(shí)間。下面的webpack的一些特性在開發(fā)插件的時(shí)候變得很有用。

探索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è)模塊管理來自于源代碼庫中的源文件的構(gòu)建。

module.fileDependencies: 包含在模塊中的源文件路徑數(shù)組。 這包括源JavaScript文件本身(例如:index.js)以及所需的所有依賴項(xiàng)資源文件(樣式表,圖像等)。 查看依賴關(guān)系對(duì)于查看哪些源文件屬于模塊很有用。

compilation.chunks: Compilation中由chunks組成的數(shù)組(構(gòu)建輸出)。 每個(gè)chunk管理最終渲染資源的組合。

chunk.modules: 包含在一個(gè)chunk中的模塊數(shù)組。 通過擴(kuò)展,您可以查看每個(gè)模塊的依賴關(guān)系,以查看傳遞到chunk中的原始源文件

chunk.files: 由chunk生成的輸出文件名的數(shù)組。 您可以從compilation.assets表訪問這些資源。

檢測(cè)觀察圖

在運(yùn)行webpack中間件時(shí),每個(gè)compilation都包含一個(gè)fileDependencies數(shù)組(正在監(jiān)視的文件)和一個(gè)將觀察文件路徑映射到時(shí)間戳的fileTimestamps哈希。 這些對(duì)于檢測(cè)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;

您還可以將新的文件路徑傳入觀察圖,以便在這些文件更改時(shí)接收compilation觸發(fā)器。 只需將有效的文件路徑推送到compilation.fileDependencies數(shù)組中即可將其添加到觀察列表中。 注意:在每個(gè)compilation中重建fileDependencies數(shù)組,因此您的插件必須將自己觀察的依賴項(xiàng)推送到每個(gè)編譯中,以使它們保持監(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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82989.html

相關(guān)文章

  • Webpack 4.0 發(fā)布:有哪些新特性?(

    摘要:有哪些新特性有哪些改進(jìn)學(xué)著使用這個(gè)新版本,來構(gòu)建更快的應(yīng)用吧。繼版本之后,花了將近八個(gè)月的時(shí)間來發(fā)布。的創(chuàng)始人之一,,建議用戶使用,以便使用最優(yōu)的性能,是因?yàn)樵创a使用了新特性。全新的插件系統(tǒng)配備了全新整改的插件系統(tǒng)。 本文原文地址:https://auth0.com/blog/webpac...第一次翻譯,不當(dāng)之處,歡迎指正 官方已經(jīng)發(fā)布了Webpack 4.0。有哪些新特性?有哪些...

    HitenDev 評(píng)論0 收藏0
  • [] 用 ES6 構(gòu)建新一代可復(fù)用 JS 模塊

    摘要:我們已經(jīng)運(yùn)用了的一些閃亮的新特性,那么如何才能轉(zhuǎn)化為的代碼呢首先,我們需要通過來安裝在全局安裝會(huì)提供我們一個(gè)命令行工具。 你是不是也在為可以使用ES6的新特性而興奮,卻不太確定應(yīng)該從哪開始,或者如何開始?不止你一個(gè)人這樣!我已經(jīng)花了一年半的時(shí)間去解決這個(gè)幸福的難題。在這段時(shí)間里 JavaScript 工具鏈中有幾個(gè)令人興奮的突破。 這些突破讓我們可以用ES6書寫完全的JS模塊,而不會(huì)為...

    phpmatt 評(píng)論0 收藏0
  • []Webpack的奇妙世界

    摘要:相反,解釋背后的原理是什么使他比一個(gè)構(gòu)造器更加強(qiáng)大。仍然是構(gòu)造器類似這樣的工具存在的主要原因之一就是解決依賴問題。是一個(gè)模塊構(gòu)造器,就是前文所說的。 Webpack是一個(gè)JavaScript模塊構(gòu)造器。 這是適合它功能的名稱。 但是,我想在本文中展現(xiàn)Webpack的真正功能。 本文將不講解如何使用Webpack。 相反,解釋背后的原理:是什么使他比一個(gè)構(gòu)造器更加強(qiáng)大。 Webpack仍...

    enali 評(píng)論0 收藏0
  • [] Webpack 前端構(gòu)建集成方案

    摘要:現(xiàn)在,讓我們創(chuàng)建項(xiàng)目的入口,并使用然后創(chuàng)建我們的配置,文件名為,的配置文件是一個(gè),并且需要成一個(gè)對(duì)象在這里,告訴那些文件是你應(yīng)用的入口。代碼分割便是用來解決之前所說的單集成模塊不可維護(hù)的引用的問題。 構(gòu)建工具逐漸成為前端工程必備的工具,Grunt、Gulp、Fis、Webpack等等,譯者有幸使用過Fis、Gulp。前者是百度的集成化方案,提供了一整套前端構(gòu)建方案,優(yōu)點(diǎn)是基本幫你搞定了...

    lewif 評(píng)論0 收藏0
  • 一個(gè)小時(shí)搭建一個(gè)全棧Web應(yīng)用框架(下)——美化與功能

    摘要:點(diǎn)擊直達(dá)前文譯一個(gè)小時(shí)搭建一個(gè)全棧應(yīng)用框架上如果沒有,但還是要繼續(xù)學(xué)習(xí)本教程,可以到我的頁面下載代碼。從服務(wù)器返回隨機(jī)語言的每當(dāng)我們與服務(wù)器上的端點(diǎn)進(jìn)行通話時(shí),為了能夠請(qǐng)求一個(gè)隨機(jī)的歐洲語言,必須更改文件中的功能。 翻譯:瘋狂的技術(shù)宅原文標(biāo)題:Creating a full-stack web application with Python, NPM, Webpack and Reac...

    Luosunce 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<