webpack output.library的16 种取值方法示例
前置准备
在项目开发中使用 webpack 打包前端代码,对 output.library 配置项总是不求甚解,只知道将代码打包成 npm 库的时候要配置它。这段时间又要开发组件库,借助这次机会对 output.library 求甚解。
配置过 output.library 的同学应该也配置过 output.libraryTarget,在开发库的时候总是一起配置它们。由于在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 的配置如下,后续我们只关注 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 运行时,代码如下,后续将不再介绍它。
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 }); };
点这里得到文本的代码。
不配置 library
在介绍 library 各配置项的作用前,先看一下不配置 library 时的打包结果。如下:
// 自执行函数 (() => { var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__) }); // 打包入口导出的函数 function __WEBPACK_DEFAULT_EXPORT__(a, b) { console.log(a + b) } })() ;
从上述代码可以看出,不配置 library 时,__WEBPACK_DEFAULT_EXPORT__
函数没有被公开,在库外部的任何位置都访问不到它。
下面将介绍配置 library 时的各种情况,library 可接受的数据类型是 string | string[] | object
。string
是 object
类型的简写形式,当值为 object
类型时,object 中能包含的属性有 name、type、export、auxiliaryComment 和 umdNamedDefine。本文将重点放在 type 字段上,它决定如何公开当前库,取值基本固定,name 字段可以是任何字符串,它用来指定库的名称。
library.type = var(默认值)
将 library 的值改成 {type: 'var', name: 'MyLibrary'}
, 打包结果如下:
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__; })()
从上述代码可以看出,通过MyLibrary
能访问到add
函数,当不能保证MyLibrary
在全局变量上。
library.type = window
将 library 的值改成 {type: 'window', name: '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) } window.MyLibrary = __webpack_exports__; })()
从上述代码可以看出,通过window.MyLibrary
能访问到add
函数。
library.type = module
将 library 的值改成 {type: 'module'}
, 此时还要 experiments.outputModule 设置为 true , 打包结果如下:
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 };
此时不存在闭包,并且能用 es modules 将库导入。
library.type = this
将 library 的值改成 {type: 'this', name: '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) } this.MyLibrary = __webpack_exports__; })()
此时通过 this.MyLibrary 能访问到 add 函数
library.type = self
将 library 的值改成 {type: 'self', name: '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) } self.MyLibrary = __webpack_exports__; })()
此时通过 self.MyLibrary 可访问到 add 函数,在浏览器环境的全局上下文中 self 等于 window
library.type = global
将 library 的值改成 {type: 'global', name: 'MyLibrary'}
,此时 MyLibrary 会被分配到全局对象,全局对象会根据target值的不同而不同,全部对象可能的值是 self、global 或 globalThis。当 target 的值为 web(默认值),代码结果如下:
(() => { 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__; })()
此时的打包结果与 library.type = self 结果一样。
library.type = commonjs
将 library 的值改成 {type: 'commonjs', name: '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) } exports.MyLibrary = __webpack_exports__; })()
顾名思义,如果公开的库要在 CommonJS 环境中使用,那么将 library.type 设置成 commonjs,此时 MyLibrary 分配给了 exports
library.type = commonjs2
将 library 的值改成 {type: 'commonjs2', name: '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) } module.exports.MyLibrary = __webpack_exports__; })()
此时 MyLibrary 分配给了 module.exports,如果公开的库要在 Node.js 环境中运行,推荐将 library.type 设置为 commonjs2。commonjs 和 commonjs2 很像,但它们有一些不同,简单的说 CommonJs 规范只定义了 exports ,但是 module.exports 被 node.js 和一些其他实现 CommonJs 规范的模块系统所使用,commonjs 表示纯 CommonJs,commonjs2 在 CommonJs 的基础上增加了 module.exports。
library.type = commonjs-static
将 library 的值改成 {type: 'commonjs-module'}
,注意此时没有设置 name 属性, 打包结果如下:
(() => { 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 模块中使用库
const add = require('./dist/main.js');
在 ESM 模块中使用库
import add from './dist/main.js';
当源代码是用 ESM 编写的,但你的库要同时兼容 CJS 和 ESM 时,library.type = commonjs-static将很有用。
library.type = amd
将 library 的值改成 {type: 'amd', name: 'MyLibrary'}
, 打包结果如下:
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__; })() ; });;
当你的库要在 amd 模块中使用时,将 library.type 设置成 amd
library.type = umd
将 library 的值改成 {type: 'umd', name: 'MyLibrary'}
, 打包结果如下:
(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__; })() ; });
此时你的库能用 Commonjs、AMD 和全局变量引入,在开发库时将 library.type 设置成 umd 很常见。
library.type = assign
将 library 的值改成 {type: 'assign', name: 'MyLibrary'}
, 打包结果如下:
(() => { 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__; })()
这将生成一个隐含的全局变量 MyLibrary,通过 MyLibrary 能访问 add 函数,它有可能覆盖一个现有值,因此要小心使用。
library.type = assign-properties
将 library 的值改成 {type: 'assign-properties', name: 'MyLibrary'}
, 打包结果如下:
(() => { 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__ 上的属性转移到 __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'}
, 打包结果如下:
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__; })() );
此时入口的源码在 jsonp 的包裹器中,这种情况要确保 MyLibrary 函数存在。
library.type = system
将 library 的值改成 {type: 'system', name: 'MyLibrary'}
, 打包结果如下:
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__; })() ); } }; });
将你的库公开为一个System 模块。
总结
当你的库导出的内容需要在另外的地方(通常是另一个项目)访问,那么你应该给 webpack 配置 library 字段,library 究竟要配置成什么值,这取决于你希望你的库怎么被引入
以上就是webpack output.library的16 种取值方法示例的详细内容,更多关于webpack output.library取值的资料请关注猪先飞其它相关文章!
原文出处:https://juejin.cn/post/7140619769853509640
相关文章
c#检测usb设备拨插类库USBClassLibrary分享
这篇文章主要介绍了c#检测usb设备拨插类库USBClassLibrary的简单示例,需要的朋友可以参考下...2020-06-25- 这两天为了这个问题, Gitter 上问, Twitter 上问, GitHub 上问, 两天没反应 原来写博客的 jlongster 不理我, 我也不知道 Webpack 作者的联系方式 最后在 Gitter 上发的消息他似乎看到了, 就粗略地解释了一遍, 醍醐灌...2015-10-23
Webpack打包css后z-index被重新计算的解决方法
这篇文章主要跟大家分享了Webpack打包css后z-index被重新计算的解决方法,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。...2017-06-24- 本文主要介绍了webpack搭建脚手架打包TypeScript代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-21
PHP启动提示Unable to load dynamic library php_curl.dll怎么办
PHP启动提示Unable to load dynamic library php_curl.dll怎么办 ,下面我们来看解决办法哦 这个问题容易手配PHP的时候出现, 在php.ini中正确开启了curl扩展后,...2016-11-25VC++ loadlibrary()加载三方dll失败, 返回错误码:126的解决方法
今天在编写VC++ loadlibrary()加载三方dll是总是失败,并且返回错误码:126,这里就为大家分享一下具体的解决方法...2021-03-15- 这篇文章主要介绍了详解vue+vueRouter+webpack的简单实例,非常具有实用价值,需要的朋友可以参考下...2017-06-24
Eclipse 和 IDEA 导入library库文件【图文步骤】
关于关于Eclipse 和 IDEA 导入library库文件,本教程使用图文并茂来详情讲解,非常实用,做Android开发的同学可以参考一下。 关于Eclipse 和 IDEA 导入library库文件,...2016-09-20- 这篇文章主要介绍了python 中dict的元素取值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-10
- 今天小编就为大家分享一篇浅谈tensorflow中张量的提取值和赋值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-22
- 本篇文章主要介绍了vue-cli webpack 开发环境跨域详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 ...2017-05-22
深入webpack打包原理及loader和plugin的实现
这篇文章主要介绍了深入webpack打包原理及loader和plugin的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-05-07- 这篇文章主要介绍了jQuery对html元素的取值与赋值,较为详细的分析了jQuery针对常见html元素的获取与赋值技巧,非常简单实用,需要的朋友可以参考下...2015-12-21
- 1、使用post方法提交表单 使用方法:把<from>表单中的method标签属性改为“post” 特点:post方法不依赖于url,不会再地址栏显示。post方法可以没有限...2016-11-25
Android Design Support Library高逼格金钱豹制作教程
本文章来为各位介绍一篇关于Android Design Support Library高逼格金钱豹制作教程,希望此教程能够帮助到各位安卓开发新手。 最近项目不是很忙,终于有时间写博客啦,...2016-09-20- 这篇文章主要给大家介绍了关于js中复选框的取值及赋值的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-18
解决PHP报错ZipArchive library is not enabled异常的方法
本文章为各位介绍一篇关于解决PHP报错ZipArchive library is not enabled异常的方法,希望文章能够对大家有帮助。 今天在Linux底下上传Excel文件时,抛出“ZipArc...2016-11-25Webpack-cli安装成功后查看webpack -v报错案例详解
这篇文章主要介绍了Webpack-cli安装成功后查看webpack -v报错案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-09-08- php教程 intval的取值范围:与操作系统相关,32位系统上为-2147483648到2147483647,64位系统上为-9223372036854775808到9223372036854775807。 mysql教程 int取值范围:与...2016-11-25
- 这篇文章主要介绍了ASP.NET新增时多字段取值解决方案,从解题思路出发分析原因,...2021-09-22