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

資訊專欄INFORMATION COLUMN

webpack組織模塊的原理 - external模塊

Lavender / 2445人閱讀

摘要:所以通常情況下當(dāng)你的庫(kù)需要依賴到例如,這樣的通用模塊時(shí),我們可以不將它打包進(jìn),而是在的配置中聲明這就是在告訴請(qǐng)不要將這個(gè)模塊注入編譯后的文件里,對(duì)于我源代碼里出現(xiàn)的任何這個(gè)模塊的語(yǔ)句,請(qǐng)將它保留。

這篇文章討論Webpack打包library時(shí)經(jīng)常需要用到的一個(gè)選項(xiàng)external,它用于避免將一些很通用的模塊打包進(jìn)你發(fā)布的library里,而是選擇把它們聲明成external的模塊,在你的library被上層使用后,在最后階段由Webpack統(tǒng)一把這個(gè)external的依賴模塊打包進(jìn)來(lái)。

external選項(xiàng)一般都是用在打包library上面,如果不是library而是一個(gè)最終的app的發(fā)布JS文件,那external也沒有什么意義。關(guān)于Webpack打包library的分析和一些選項(xiàng)的作用,我在前一篇文章做了討論。

external選項(xiàng)

我們?nèi)匀皇褂们耙黄恼碌睦樱x一個(gè)庫(kù)util.js

import $ from "jquery"

function hideImages() {
  $("img").hide();
}

export default {
  "hideImages": hideImages
}

我們使用Webpack打包發(fā)布這個(gè)庫(kù):

// 入口文件
entry: {
  util: "./util.js",
}

// 輸出文件
output: {
  path: "./dist",
  filename: "[name].dist.js"

  library: "util",
  libraryTarget: commonjs2,
  targetExport: "default"
}

這樣打包出來(lái)的util.dist.js文件會(huì)把jquery的代碼完整地注入進(jìn)去,因?yàn)槟愕脑创a使用到了它。但是這往往并不是我們希望的,因?yàn)?b>jquery是很通用的模塊,在一個(gè)app中,很可能其它的庫(kù)也會(huì)用到它,最頂層的入口文件app也可能用到它,如果每一個(gè)庫(kù)模塊的發(fā)布版本都將jquery原封不動(dòng)地打包進(jìn)了自己的bundle,最后拼到一起,在最終的app發(fā)布代碼里就會(huì)有很多份jquery的復(fù)制,當(dāng)然這可能并不會(huì)影響它的正常功能,但是會(huì)占據(jù)很大的代碼體積。

所以通常情況下當(dāng)你的庫(kù)需要依賴到例如jquery,bootstrap這樣的通用JS模塊時(shí),我們可以不將它打包進(jìn)bundle,而是在Webpack的配置中聲明external

externals: {
  jquery: {
    root: "jquery",
    commonjs: "jquery",
    commonjs2: "jquery",
    amd: "jquery",
  },
},

這就是在告訴Webpack:請(qǐng)不要將這個(gè)模塊注入編譯后的JS文件里,對(duì)于我源代碼里出現(xiàn)的任何import/require這個(gè)模塊的語(yǔ)句,請(qǐng)將它保留。

我們可以看一下編譯后的bundle文件的結(jié)構(gòu):

module.exports = (function(modules) {
  var installedModules = {};
  function webpack_require(moduleId) {
     // ...
  }
  return webpack_require("./util.js");
}) ({
  "./util.js": generated_util,
  // "/path/to/jquery.js": generated_jquery 原本有這一行,現(xiàn)在被刪去。
});

可以看到jquery模塊沒有被打包進(jìn)bundle文件,而對(duì)于util,它的生成代碼即generated_util函數(shù)中關(guān)于import jquery相關(guān)的語(yǔ)句也被保留了原意:

function generated_util(module, exports, webpack_require) {
  var $ = require("jquery");
  // util的其它源代碼
  // ...
}

當(dāng)然也并非完全沒有修改,例如將import的改回了傳統(tǒng)的require關(guān)鍵詞,因?yàn)槲覀冞@里用的是CommonJS風(fēng)格的打包方式。不過(guò)這些都是次要的,關(guān)鍵是它保留了require這個(gè)關(guān)鍵詞,而沒有使用webpack_require將jquery真的引入進(jìn)來(lái)。這就是說(shuō),當(dāng)前的這個(gè)JS文件的模塊管理系統(tǒng)中是沒有jquery的,它是一個(gè)external的模塊,需要在這個(gè)JS文件被其它人引用并且在上層編譯時(shí),jquery才可能被真的引入進(jìn)來(lái),到那個(gè)時(shí)候這里的require關(guān)鍵詞才會(huì)被替換為webpack_require。

對(duì)于external的依賴模塊,通常你可以這樣做,例如你使用npm發(fā)布你的庫(kù),你可以將jquery在package.json文件中添加到dependencies,這樣別人npm install你發(fā)布的庫(kù)時(shí),jquery也會(huì)被自動(dòng)下載到node_modules供別人打包使用。

umd格式下的打包

如果我們使用umd格式打包,我們可以看到在不同環(huán)境中,external模塊是如何發(fā)揮作用的:

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === "object" && typeof module === "object")  // commonjs2
    module.exports = factory(require("jquery"));
  else if(typeof define === "function" && define.amd)
    define("util", ["jquery"], factory);  // amd
  else if(typeof exports === "object")
    exports["util"] = factory(require("jquery"));  // commonjs
  else
    root["util"] = factory(root["jquery"]);  // var
}) (window, function(__webpack_external_module_jquery__) {
  return (function(modules) {
    var installedModules = {};
    function webpack_require(moduleId) {
       // ...
    }
    return webpack_require("./util.js");
  }) ({
    "./util.js": generated_util,
  });
}

generated_util也相應(yīng)地增加一個(gè)參數(shù)__webpack_external_module_jquery__

function generated_util(module, exports, webpack_require,
                        __webpack_external_module_jquery__) {
  var $ = __webpack_external_module_jquery__;
  // util的其它源代碼
  // ...
}

這樣的寫法似乎結(jié)構(gòu)和上面的CommonJS的編譯版本不太一樣,但實(shí)際上本質(zhì)是一樣的。因?yàn)楝F(xiàn)在umd要照顧到不同的運(yùn)行環(huán)境,所以它把require("jquery")提前了,作為factory的參數(shù)傳入。對(duì)于每種運(yùn)行環(huán)境,各有各的做法:

CommonJS:保留require("jquery")語(yǔ)句。

AMD:在define中將jquery定義為依賴模塊。

Var:從全局域中取出jquery變量,這需要jquery在該模塊之前就已經(jīng)被加載。

然后不管是哪種情況,它們都將載入后的jquery模塊作為參數(shù)傳入factory函數(shù),這樣就能正確加載util模塊了。

以上涉及到Webpack生成代碼的部分可能有點(diǎn)繞,需要你比較了解Webpack打包模塊的機(jī)制和原理,關(guān)于這部分我在這篇文章里做了詳細(xì)討論。

總結(jié)

以上就是關(guān)于Webpack的external選項(xiàng)的使用,并且從編譯后的JS代碼分析了它到底是如何起作用的。我想閱讀Webpack相關(guān)的生成代碼還是很重要的,這樣才算是真正地理解了external的機(jī)制,在碰到一些坑時(shí)才能知道怎么去debug。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

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

相關(guān)文章

  • webpack 構(gòu)建性能優(yōu)化策略小結(jié)

    摘要:但是,隨者工程開發(fā)的復(fù)雜程度和代碼規(guī)模不斷地增加,暴露出來(lái)的各種性能問(wèn)題也愈發(fā)明顯,極大的影響著開發(fā)過(guò)程中的體驗(yàn)。對(duì)應(yīng)的資源也可以直接由頁(yè)面外鏈載入,有效地減小了資源包的體積。 背景 如今前端工程化的概念早已經(jīng)深入人心,選擇一款合適的編譯和資源管理工具已經(jīng)成為了所有前端工程中的標(biāo)配,而在諸多的構(gòu)建工具中,webpack以其豐富的功能和靈活的配置而深受業(yè)內(nèi)吹捧,逐步取代了grunt和gu...

    hiYoHoo 評(píng)論0 收藏0
  • webpack組織模塊原理 - 基礎(chǔ)篇

    摘要:每一個(gè)模塊的源代碼都會(huì)被組織在一個(gè)立即執(zhí)行的函數(shù)里。接下來(lái)看的生成代碼可以看到,的源代碼中關(guān)于引入的模塊的部分做了修改,因?yàn)闊o(wú)論是,或是風(fēng)格的,都無(wú)法被解釋器直接執(zhí)行,它需要依賴模塊管理系統(tǒng),把這些抽象的關(guān)鍵詞具體化。 現(xiàn)在前端用Webpack打包JS和其它文件已經(jīng)是主流了,加上Node的流行,使得前端的工程方式和后端越來(lái)越像。所有的東西都模塊化,最后統(tǒng)一編譯。Webpack因?yàn)榘姹镜?..

    leiyi 評(píng)論0 收藏0
  • webpack組織模塊原理 - 打包Library

    摘要:所以你編譯后的文件實(shí)際上應(yīng)當(dāng)只輸出,這就需要在配置里用來(lái)控制這樣上面的模塊加載函數(shù)會(huì)在返回值后面加一個(gè),這樣就只返回的部分。 之前一篇文章分析了Webpack打包JS模塊的基本原理,所介紹的案例是最常見的一種情況,即多個(gè)JS模塊和一個(gè)入口模塊,打包成一個(gè)bundle文件,可以直接被瀏覽器或者其它JavaScript引擎執(zhí)行,相當(dāng)于直接編譯生成一個(gè)完整的可執(zhí)行的文件。不過(guò)還有一種很常見的...

    legendmohe 評(píng)論0 收藏0
  • 我他喵到底要怎樣才能在生產(chǎn)環(huán)境中用上 ES6 模塊化?

    摘要:因此,你還是需要各種各樣雜七雜八的工具來(lái)轉(zhuǎn)換你的代碼噢,我可去你媽的吧,這些東西都是干嘛的我就是想用個(gè)模塊化,我到底該用啥子本文正旨在列出幾種可用的在生產(chǎn)環(huán)境中放心使用模塊化的方法,希望能幫到諸位后來(lái)者這方面的中文資源實(shí)在是忒少了。 原文發(fā)表在我的博客上。最近搗鼓了一下 ES6 的模塊化,分享一些經(jīng)驗(yàn) :) Python3 已經(jīng)發(fā)布了九年了,Python 社區(qū)卻還在用 Python 2...

    KaltZK 評(píng)論0 收藏0
  • webpack實(shí)戰(zhàn)

    摘要:和類似的預(yù)處理器還有等。的用處非常多,包括給自動(dòng)加前綴使用下一代語(yǔ)法等,目前越來(lái)越多的人開始用它,它很可能會(huì)成為預(yù)處理器的最終贏家。 webpack實(shí)戰(zhàn) 查看所有文檔頁(yè)面:全棧開發(fā),獲取更多信息。快馬加鞭,加班加點(diǎn),終于把這個(gè)文檔整理出來(lái)了,順便深入地學(xué)習(xí)一番,鞏固知識(shí),就是太累人,影響睡眠時(shí)間和質(zhì)量。極客就是想要把事情做到極致,開始了就必須到達(dá)終點(diǎn)。 原文鏈接:webpack實(shí)戰(zhàn),原...

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

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

0條評(píng)論

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