webpack?output.library的16?種取值方法示例
前置準(zhǔn)備
在項(xiàng)目開發(fā)中使用 webpack 打包前端代碼,對(duì) output.library 配置項(xiàng)總是不求甚解,只知道將代碼打包成 npm 庫(kù)的時(shí)候要配置它。這段時(shí)間又要開發(fā)組件庫(kù),借助這次機(jī)會(huì)對(duì) output.library 求甚解。
配置過(guò) output.library 的同學(xué)應(yīng)該也配置過(guò) output.libraryTarget,在開發(fā)庫(kù)的時(shí)候總是一起配置它們。由于在webpack文檔中推薦使用 output.library.type 代替 output.libraryTarget,所以本文只介紹 output.library。
本文 webpack 的版本是 5.74.0。
入口代碼如下:
// index.js
export default function add(a, b) {
console.log(a + b)
}
webpack 的配置如下,后續(xù)我們只關(guān)注 library 字段。
const path = require('path');
module.exports = {
entry: './index.js',
mode: "none",
output: {
filename: 'main.js',
// library: 'MyLibrary',
path: path.resolve(__dirname, 'dist'),
},
};
打包輸出的文件中,除了包含 index.js 中的源碼,還包含 webpack 運(yùn)行時(shí),代碼如下,后續(xù)將不再介紹它。
var __webpack_require__ = {};
// 將 definition 中的屬性添加到 exports 上
__webpack_require__.d = (exports, definition) => {
for(var key in definition) {
if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
}
}
};
// 判斷 obj 上是否有 prop
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
// 在 exports 上定義 __esModule 屬性
__webpack_require__.r = (exports) => {
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
點(diǎn)這里得到文本的代碼。
不配置 library
在介紹 library 各配置項(xiàng)的作用前,先看一下不配置 library 時(shí)的打包結(jié)果。如下:
// 自執(zhí)行函數(shù)
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)
});
// 打包入口導(dǎo)出的函數(shù)
function __WEBPACK_DEFAULT_EXPORT__(a, b) {
console.log(a + b)
}
})()
;
從上述代碼可以看出,不配置 library 時(shí),__WEBPACK_DEFAULT_EXPORT__ 函數(shù)沒(méi)有被公開,在庫(kù)外部的任何位置都訪問(wèn)不到它。
下面將介紹配置 library 時(shí)的各種情況,library 可接受的數(shù)據(jù)類型是 string | string[] | object。string 是 object 類型的簡(jiǎn)寫形式,當(dāng)值為 object 類型時(shí),object 中能包含的屬性有 name、type、export、auxiliaryComment 和 umdNamedDefine。本文將重點(diǎn)放在 type 字段上,它決定如何公開當(dāng)前庫(kù),取值基本固定,name 字段可以是任何字符串,它用來(lái)指定庫(kù)的名稱。
library.type = var(默認(rèn)值)
將 library 的值改成 {type: 'var', name: 'MyLibrary'}, 打包結(jié)果如下:
var MyLibrary;
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
MyLibrary = __webpack_exports__;
})()
從上述代碼可以看出,通過(guò)MyLibrary能訪問(wèn)到add函數(shù),當(dāng)不能保證MyLibrary在全局變量上。
library.type = window
將 library 的值改成 {type: 'window', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
window.MyLibrary = __webpack_exports__;
})()
從上述代碼可以看出,通過(guò)window.MyLibrary能訪問(wèn)到add函數(shù)。
library.type = module
將 library 的值改成 {type: 'module'}, 此時(shí)還要 experiments.outputModule 設(shè)置為 true , 打包結(jié)果如下:
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
var __webpack_exports__default = __webpack_exports__["default"];
export { __webpack_exports__default as default };
此時(shí)不存在閉包,并且能用 es modules 將庫(kù)導(dǎo)入。
library.type = this
將 library 的值改成 {type: 'this', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
this.MyLibrary = __webpack_exports__;
})()
此時(shí)通過(guò) this.MyLibrary 能訪問(wèn)到 add 函數(shù)
library.type = self
將 library 的值改成 {type: 'self', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
self.MyLibrary = __webpack_exports__;
})()
此時(shí)通過(guò) self.MyLibrary 可訪問(wèn)到 add 函數(shù),在瀏覽器環(huán)境的全局上下文中 self 等于 window
library.type = global
將 library 的值改成 {type: 'global', name: 'MyLibrary'},此時(shí) MyLibrary 會(huì)被分配到全局對(duì)象,全局對(duì)象會(huì)根據(jù)target值的不同而不同,全部對(duì)象可能的值是 self、global 或 globalThis。當(dāng) target 的值為 web(默認(rèn)值),代碼結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
self.MyLibrary = __webpack_exports__;
})()
此時(shí)的打包結(jié)果與 library.type = self 結(jié)果一樣。
library.type = commonjs
將 library 的值改成 {type: 'commonjs', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
exports.MyLibrary = __webpack_exports__;
})()
顧名思義,如果公開的庫(kù)要在 CommonJS 環(huán)境中使用,那么將 library.type 設(shè)置成 commonjs,此時(shí) MyLibrary 分配給了 exports
library.type = commonjs2
將 library 的值改成 {type: 'commonjs2', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
module.exports.MyLibrary = __webpack_exports__;
})()
此時(shí) MyLibrary 分配給了 module.exports,如果公開的庫(kù)要在 Node.js 環(huán)境中運(yùn)行,推薦將 library.type 設(shè)置為 commonjs2。commonjs 和 commonjs2 很像,但它們有一些不同,簡(jiǎn)單的說(shuō) CommonJs 規(guī)范只定義了 exports ,但是 module.exports 被 node.js 和一些其他實(shí)現(xiàn) CommonJs 規(guī)范的模塊系統(tǒng)所使用,commonjs 表示純 CommonJs,commonjs2 在 CommonJs 的基礎(chǔ)上增加了 module.exports。
library.type = commonjs-static
將 library 的值改成 {type: 'commonjs-module'},注意此時(shí)沒(méi)有設(shè)置 name 屬性, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
exports["default"] = __webpack_exports__["default"];
Object.defineProperty(exports, "__esModule", { value: true });
})()
在 CommonJS 模塊中使用庫(kù)
const add = require('./dist/main.js');
在 ESM 模塊中使用庫(kù)
import add from './dist/main.js';
當(dāng)源代碼是用 ESM 編寫的,但你的庫(kù)要同時(shí)兼容 CJS 和 ESM 時(shí),library.type = commonjs-static將很有用。
library.type = amd
將 library 的值改成 {type: 'amd', name: 'MyLibrary'}, 打包結(jié)果如下:
define("MyLibrary", [], () => { return /******/ (() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
return __webpack_exports__;
})()
;
});;
當(dāng)你的庫(kù)要在 amd 模塊中使用時(shí),將 library.type 設(shè)置成 amd
library.type = umd
將 library 的值改成 {type: 'umd', name: 'MyLibrary'}, 打包結(jié)果如下:
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object') // commonjs2
module.exports = factory();
else if(typeof define === 'function' && define.amd) // amd
define([], factory);
else if(typeof exports === 'object') // commonjs
exports["MyLibrary"] = factory();
else // 全局變量
root["MyLibrary"] = factory();
})(self, () => {
return /******/ (() => { // webpackBootstrap
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
return __webpack_exports__;
})()
;
});
此時(shí)你的庫(kù)能用 Commonjs、AMD 和全局變量引入,在開發(fā)庫(kù)時(shí)將 library.type 設(shè)置成 umd 很常見(jiàn)。
library.type = assign
將 library 的值改成 {type: 'assign', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
})();
MyLibrary = __webpack_exports__;
})()
這將生成一個(gè)隱含的全局變量 MyLibrary,通過(guò) MyLibrary 能訪問(wèn) add 函數(shù),它有可能覆蓋一個(gè)現(xiàn)有值,因此要小心使用。
library.type = assign-properties
將 library 的值改成 {type: 'assign-properties', name: 'MyLibrary'}, 打包結(jié)果如下:
(() => {
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
(() => {
"use strict";
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
})();
var __webpack_export_target__ = (MyLibrary = typeof MyLibrary === "undefined" ? {} : MyLibrary);
// 將 __webpack_exports__ 上的屬性轉(zhuǎn)移到 __webpack_export_target__ 上。
for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
})()
它與 assign 類似,但更安全,如果 MyLibrary 存在,那么它將重用 MyLibrary,而非覆蓋。
library.type = jsonp
將 library 的值改成 {type: 'jsonp', name: 'MyLibrary'}, 打包結(jié)果如下:
MyLibrary((() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
return __webpack_exports__;
})()
);
此時(shí)入口的源碼在 jsonp 的包裹器中,這種情況要確保 MyLibrary 函數(shù)存在。
library.type = system
將 library 的值改成 {type: 'system', name: 'MyLibrary'}, 打包結(jié)果如下:
System.register("MyLibrary", [], function(__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {
return {
execute: function() {
__WEBPACK_DYNAMIC_EXPORT__(
(() => {
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
"default": () => (/* binding */ add)
});
function add(a, b) {
console.log(a + b)
}
return __webpack_exports__;
})()
);
}
};
});
將你的庫(kù)公開為一個(gè)System 模塊。
總結(jié)
當(dāng)你的庫(kù)導(dǎo)出的內(nèi)容需要在另外的地方(通常是另一個(gè)項(xiàng)目)訪問(wèn),那么你應(yīng)該給 webpack 配置 library 字段,library 究竟要配置成什么值,這取決于你希望你的庫(kù)怎么被引入
以上就是webpack output.library的16 種取值方法示例的詳細(xì)內(nèi)容,更多關(guān)于webpack output.library取值的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS返回只包含數(shù)字類型的數(shù)組實(shí)例分析
這篇文章主要介紹了JS返回只包含數(shù)字類型的數(shù)組實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了循環(huán)遍歷數(shù)組及正則匹配兩種實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-12-12
使用Fuse.js實(shí)現(xiàn)高效的模糊搜索功能
在現(xiàn)代?Web?應(yīng)用程序中,實(shí)現(xiàn)高效的搜索功能是至關(guān)重要的,Fuse.js?是一個(gè)強(qiáng)大的?JavaScript?庫(kù),它提供了靈活的模糊搜索和文本匹配功能,使您能夠輕松實(shí)現(xiàn)出色的搜索體驗(yàn),文中代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-01-01
JavaScript中async與await實(shí)現(xiàn)原理與細(xì)節(jié)
這篇文章主要介紹了JavaScript中async與await實(shí)現(xiàn)原理與細(xì)節(jié),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
javascript實(shí)現(xiàn)簡(jiǎn)單放大鏡效果
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)簡(jiǎn)單放大鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
使用 JavaScript 創(chuàng)建并下載文件(模擬點(diǎn)擊)
本文將介紹如何使用 JavaScript 創(chuàng)建文件,并自動(dòng)/手動(dòng)將文件下載,這在導(dǎo)出原始數(shù)據(jù)時(shí)會(huì)比較方便2019-10-10
JavaScript 嚴(yán)格模式(use strict)用法實(shí)例分析
這篇文章主要介紹了JavaScript 嚴(yán)格模式(use strict)用法,結(jié)合實(shí)例形式分析了JavaScript 嚴(yán)格模式的基本功能、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-03-03
BootStrap daterangepicker 雙日歷控件
這篇文章主要介紹了BootStrap daterangepicker 雙日歷控件,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-06-06

