首頁 > web前端 > js教程 > 主體

在webpack中如何使用external模組

亚连
發布: 2018-05-31 13:51:15
原創
2197 人瀏覽過

本篇文章主要介紹了webpack external模組的具體使用,現在分享給大家,也給大家做個參考。

這篇文章討論Webpack打包library時經常需要用到的一個選項external,它用於避免將一些很通用的模組打包進你發布的library裡,而是選擇把它們聲明成external的模組,在你的library被上層使用後,在最後階段由Webpack統一把這個external的依賴模組打包進來。

external選項一般都是用在打包library上面,如果不是library而是一個最終的app的發布JS文件,那external也沒有什麼意義。關於Webpack打包library的分析和一些選項的作用,我在前一篇文章做了討論。

external選項

我們仍然使用前一篇文章的例子,定義一個庫util.js:

import $ from 'jquery'

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

export default {
 "hideImages": hideImages
}
登入後複製

我們使用Webpack打包發布這個庫:

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

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

 library: 'util',
 libraryTarget: commonjs2,
 targetExport: 'default'
}
登入後複製

這樣打包出來的util.dist.js檔案會把jquery的程式碼完整地註入進去,因為你的原始碼使用到了它。但這往往不是我們希望的,因為jquery是很通用的模組,在一個app中,很可能其它的庫也會用到它,最頂層的入口文件app也可能用到它,如果每一個庫模組的發布版本都將jquery原封不動地打包進了自己的bundle,最後拼到一起,在最終的app發布代碼裡就會​​有很多份jquery的複製,當然這可能並不會影響它的正常功能,但是會佔據很大的程式碼體積。

所以通常當你的函式庫需要依賴到例如jquery,bootstrap這樣的通用JS模組時,我們可以不將它打包進bundle,而是在Webpack的設定中宣告external:

externals: {
 jquery: {
  root: 'jquery',
  commonjs: 'jquery',
  commonjs2: 'jquery',
  amd: 'jquery',
 },
},
登入後複製

這就是在告訴Webpack:請不要將這個模組注入編譯後的JS檔案裡,對於我原始碼裡出現的任何import/require這個模組的語句,請將它保留。

我們可以看一下編譯後的bundle文件的結構:

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 原本有这一行,现在被删去。
});
登入後複製

可以看到jquery模組沒有被打包進bundle文件,而對於util,它的生成代碼即generated_util函數中關於import jquery相關的語句也被保留了原意:

function generated_util(module, exports, webpack_require) {
 var $ = require('jquery');
 // util的其它源代码
 // ...
}
登入後複製

當然也並非完全沒有修改,例如將import的改回了傳統的require關鍵字,因為我們這裡用的是CommonJS風格的打包方式。不過這些都是次要的,關鍵是它保留了require這個關鍵字,而沒有使用webpack_require將jquery真的引入進來。這就是說,當前的這個JS檔案的模組管理系統中是沒有jquery的,它是一個external的模組,需要在這個JS檔案被其它人引用並且在上層編譯時,jquery才可能被真的引入進來,到那時這裡的require關鍵字才會被替換為webpack_require。

對於external的依賴模組,通常你可以這樣做,例如你使用npm發布你的庫,你可以將jquery在package.json文件中添加到dependencies,這樣別人npm install你發布的庫時,jquery也會自動下載到node_modules供別人打包使用。

umd格式下的打包

如果我們使用umd格式打包,我們可以看到在不同環境中,external模組是如何發揮作用的:

(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也相應地增加一個參數__webpack_external_module_jquery__:

function generated_util(module, exports, webpack_require,
            __webpack_external_module_jquery__) {
 var $ = __webpack_external_module_jquery__;
 // util的其它源代码
 // ...
}
登入後複製

這樣的寫法似乎結構和上面的CommonJS的編譯版本不太一樣,但實際上本質是一樣的。因為現在umd要照顧到不同的運作環境,所以它把require('jquery')提前了,作為factory的參數傳入。對於每種運作環境,各有各的做法:

  1. CommonJS:保留require('jquery')語句。

  2. AMD:在define中將jquery定義為依賴模組。

  3. Var:從全域域中取出jquery變量,這需要jquery在該模組之前就已經載入。

然後不管是哪種情況,它們都將載入後的jquery模組作為參數傳入factory函數,這樣就能正確載入util模組了。

以上涉及Webpack生成程式碼的部分可能有點繞,需要你比較了解Webpack打包模組的機制和原理,關於這部分我在這篇文章裡做了詳細討論。

總結

以上就是關於Webpack的external選項的使用,並且從編譯後的JS程式碼分析了它到底是如何運作的。我想閱讀Webpack相關的生成程式碼還是很重要的,這樣才算是真正理解了external的機制,在碰到一些坑洞時才能知道怎麼去debug。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

基於datepicker定義自己的angular時間元件的範例

解決Vue.js 2.0 有時雙向綁定img src屬性失敗的問題

Vue.js 動態為img的src賦值方法

#

以上是在webpack中如何使用external模組的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板