libraryTarget的幾種選擇咱們來好好分析

很久沒寫庫了,發現時代變了node

這一切的原由都是由於那隻pm,整個一個奇奇怪怪的需求,而後發現須要寫庫了,就在我流利的初始化項目時,忽然腦抽風的發現,library配置貌似不太對,libraryTarget配置貌似也不太對,因此仍是停下來吧,好好分析回顧一下,阿西吧。webpack

先來回顧一下,library是指定義一個全局使用的名稱變量,libraryTarget是指設置library的暴露方式,是commonjs、commonjs二、umd仍是this、var等。web

變量定義:瀏覽器

  • libraryTarget:「assign」,暴露一個未定義的library設置的變量。在node環境不支持。
  • libraryTarget:「var」,暴露一個用var 定義的library設置的變量。在node環境下不支持。

這兩個屬性,都是在全局建立一個變量,只有定義與未定義的區別,而且並不能在nodejs中得的支持,而且存在變量衝突的可能性。模塊化

觀察一下libraryTarget:「assign」 or 「var」產出的代碼,只是建立了一個library裏設置的變量,而後經過webpack的方法作一個導出。函數

對象定義:ui

  • libraryTarget:「window」,在window對象上定一個library設置的變量。在node環境下不支持。
  • libraryTarget:「global」,在global對象上定義一個library設置的變量。受target屬性影響,當target爲默認值web時,會在window上註冊,若是你想在global上註冊,必須修改target爲node。
  • libraryTarget:「this」,在當前this對象上定義一個library設置的變量,若是this是window,就在window。在node的環境中,若是沒指定require賦值的變量,並不會在指向global。

這三個屬性的特徵都是在公共對象上export出你的方法函數。特色無非是減小了變量衝突的可能性,可是依舊沒有解決問題,只有global模式支持在node環境中,還必須設置target爲node否則也是不支持的。this

觀察一下libraryTarget:「window」 or 「global」 or 「this」產出的代碼,在相應的libraryTarget設置的對象上,建立一個library設置的變量,而後根據webpack的方法作一個導出。global有一個注意點,那就是target配置。若是沒有寫那默認是在window對象上註冊。cdn

模塊定義:對象

  • libraryTarget:「commonjs」,在export對象上定義library設置的變量。在node中支持,瀏覽器中不支持。
  • libraryTarget:「commonjs2」,直接用module.export導出export,會忽略library設置的變量。在node中支持,在瀏覽器中不支持。
  • libraryTarget:「amd」,在define方法上定義library設置的變量,不能用script直接引用,必須經過第三方模塊RequireJS來時用

這兩個屬性,是符合模塊化規範的產物,commonjs是在export上定義library設置的變量,commonjs2是用module.export直接export的。amd的依賴前置方案在瀏覽器、node中都必須額外引入RequireJS來使用。

commonjs/commonjs2,查看源碼的話,commonjs是在exports中建立一個library設置的變量,而commonjs2是直接把方法export到module.exports中,這就是爲何commonjs2會忽略library的緣由。

amd那就是在define的方法中設置了library,這樣就能符合RequireJS的使用規範。

兼容的模塊化定義:

  • libraryTarget:「umd」,該方案支持commonjs、commonjs二、amd,能夠在瀏覽器、node中通用。

可是若是你想作到這一點,必需要額外設置,umdNamedDefine: true,globalObject: ‘this’,umdNamedDefine爲設置amd前置名稱使用library設置的變量,globalObject爲改變全局指向。這樣就能保證你的庫在node和瀏覽器中通用了。固然便捷的引入必定會帶來必定的冗餘,這就看你如何取捨了。

umd的核心沒法是webpackUniversalModuleDefinition中的判斷,這裏會作環境判斷,去使其可以使用,這裏有必要注意兩個關注點,那就是window對象,這個對象在node中是沒法使用的,而且會報錯。並且define([var])的var爲空值這也會在RequireJS中報錯。若是你須要在node、RequireJS中使用,那麼就須要額外配置umdNamedDefine、globalObject了。

這樣,你的define和window就符合要求了。

最後建議,若是目標明確,我只是兼容nodejs,那麼選擇commonjs/commonjs2,若是隻兼容瀏覽器,那就選擇暴露變量的方式,若是想通用,那就選擇umd的方式,對於不一樣的狀況作多種處理方式,是很是明智的選擇。

最後附上表格一張,僅供參考。


想找我深刻了解的話,能夠來這裏喲(。・ω・。)

相關文章
相關標籤/搜索