若是咱們僅僅是實現一個項目,咱們大機率不會關注到webpack output中的這兩個屬性。可是若是咱們是實現一個組件庫,那麼這兩個屬性就變得相當重要了。本文從本身以前遇到的一個問題提及,繼而引伸出library和libraryTarget屬性。
當我本身開始寫第一個組件庫的時候,很快我就擼好了框架的代碼,而後我興致沖沖的把個人組件庫引入到個人項目中,我記得那時候我是這麼寫的:vue
組件庫:react
import Feeds from '@/components/feeds/index'; export { Feeds, };
主項目:webpack
import Feeds from '@/tencent/newsH5Ad'; // 一些其餘代碼 <Feeds data='xxx'>
而後我就收穫了一個報錯,Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: null
。啊?難道是個人最終輸出代碼有問題?我檢查了一下最終輸出的代碼,沒有問題,Feed組件的代碼也在裏面。這個問題我查了好久,都沒有答案,最後才發現是webpack打包的問題。這就涉及到了本文的主角,library和libraryTarget。web
咱們都知道,webpack能夠將不一樣的模塊化方式(commonjs, AMD, CMD, ES6 Module)的代碼打包。那咱們打出來的代碼包其實也能夠按不一樣的模塊化方式生成,因此:json
libraryTarget就是配置webpack打包內容的模塊方式的參數
而 library就是webpack打包內容的名字
因此library規定了組件庫返回值的名字,libraryTarget規定了返回值的編碼格式。瀏覽器
libraryTarget的配置選項能夠分爲四大類:框架
也就是咱們這個問題的解決方法,因爲我寫的是一個React的UI組件庫,因此咱們須要commonjs的模塊方式。所以只須要在webpack.config.js中配置這一項便可:異步
module.exports = { entry: './src/index.js', output: { filename: 'index.js', // library: 'MyLibrary', // 模塊名稱 libraryTarget: 'commonjs2', // 輸出格式 }, // 其餘代碼 }
事實上,你能夠選擇的選項有:模塊化
commonjs/commonjs2: 將你的library暴露爲CommonJS模塊
amd: 將你的library暴露爲amd模塊
umd: 將你的library暴露爲全部的模塊定義下均可運行的方式
其中AMD和UMD須要指定library,若是不聲明組件庫則不能正常運行。這是爲了在瀏覽器上經過script標籤加載時,用AMD模塊方式輸出的組件庫能夠有明確的模塊名。如:jsonp
define("MyLibrary", [], function() { return _entry_return_; // 此模塊返回值,是入口 chunk 返回的值 });
注意:commonjs和commonjs2幾乎相同,只不過commonjs只包含exports,而commonjs2還包含module.exports,因此直接使用commonjs2便可。
libraryTarget的默認值是var,顧名思義,就是將組件庫入口起點的返回值生成一個變量。如:
var MyLibrary = _entry_return_;
也能夠選擇‘assign',那樣的話將默認生成和一個全局的變量。無論是var仍是assign,都須要設置library的名稱,不然就會報錯。
和第二種狀況差很少,只不過會把這個變量賦值給某個對象,做爲它的一個屬性存在。能夠選擇的選項有:
this: 返回值成爲this的一個屬性
window: 返回值成爲window的一個屬性
global: 返回值成爲global的一個屬性
例如:
this["MyLibrary"] = _entry_return_; window["MyLibrary"] = _entry_return_; global["MyLibrary"] = _entry_return_;
能夠看到,這種狀況下也必須指定library的名字。
在這種狀況下,libraryTarget的值爲‘jsonp’,組件庫入口起點的返回值,會被包裹到一個jsonp包裝容器中,並配合webpack的externals使用——組件庫的依賴由externals指定。如:
MyLibrary(_entry_return_);
本文介紹了webpack中libraray和libraryTarget的相關內容,解釋了爲何不設置它們時使用webpack打包出來的組件庫會有問題。通常狀況下,做爲vue或者react組件庫,libraryTarget在commonjs2,amd,umd中三者擇其一便可。