上周在做一个公用代码,计划导出为umd的格式,以同时支持 import
、 require
和 <script>
直接引用。
为了方便后续的演示,假设要处理的源代码如下:
export default { name: 'hello umd', };
webpack是一个简单好用的工具,简单配置了一下,便开始编译。初始的核心配置如下:
const config = { entry: './src/index.js', output: { filename: 'index.js', path: path.resolve(__dirname, 'dist'), library: "friendly", libraryTarget: "umd" } };
只需要在output选项中指定输出的目标是“umd”格式,同时为 <script>
的引用格式指定一个全局访问的变量名(上面的配置中是 friendly
)。
执行打包命令之后,代码会被umd的代码生命封装,如下所示:
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["friendly"] = factory(); else root["friendly"] = factory(); })(typeof self !== 'undefined' ? self : this, function() { // 模块代码 });
上面的代码中,第一个if兼容commonjs2,第二个if兼容amd,第三个兼容commonjs,第四个是普通的导出到全局变量window。
代码如此简单,代码也不存在什么问题,但上面的配置是存在问题的。如果不存在问题,也就没有本文了。将导出生成的使用的时候,出现了问题, <script>
引用之后,在浏览器中的输出(删除了不必要的代码)如下:
console.log(friendly); { __esModule: true default: { name: "hello umd" } }
多了一层default,同事使用的时候就必须用 friendly.default
的写法,好丑陋,不能这样做。便想办法去掉。
逐个测试webpack文档中相关的属性,终于找到一个属性是:
libraryExport: "default"
加上这行配置,测试一下,通了。在浏览器中的输出结果为:
console.log(friendly); { name: "hello umd" }
原因是,在上述源码的工厂函数中导出增加了 ["default"]
属性读取。
测试了一下基于babel的import语法引用也正常,原因跟webpack的封装中对 default
的处理相关。
Todo
测试加上这行代码后,AMD、CommonJS、import等的变化。目前上面的结论仅在 script
的普通引用和基于babel+webpack的import引用中测试通过。
参考
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。