很久没写库了,发现时代变了node
这一切的原由都是由于那只pm,整个一个奇奇怪怪的需求,而后发现须要写库了,就在我流利的初始化项目时,忽然脑抽风的发现,library配置貌似不太对,libraryTarget配置貌似也不太对,因此仍是停下来吧,好好分析回顾一下,阿西吧。webpack
先来回顾一下,library是指定义一个全局使用的名称变量,libraryTarget是指设置library的暴露方式,是commonjs、commonjs二、umd仍是this、var等。web
变量定义:浏览器
这两个属性,都是在全局建立一个变量,只有定义与未定义的区别,而且并不能在nodejs中得的支持,而且存在变量冲突的可能性。模块化
观察一下libraryTarget:“assign” or “var”产出的代码,只是建立了一个library里设置的变量,而后经过webpack的方法作一个导出。函数
对象定义:ui
这三个属性的特征都是在公共对象上export出你的方法函数。特色无非是减小了变量冲突的可能性,可是依旧没有解决问题,只有global模式支持在node环境中,还必须设置target为node否则也是不支持的。this
观察一下libraryTarget:“window” or “global” or “this”产出的代码,在相应的libraryTarget设置的对象上,建立一个library设置的变量,而后根据webpack的方法作一个导出。global有一个注意点,那就是target配置。若是没有写那默认是在window对象上注册。cdn
模块定义:对象
这两个属性,是符合模块化规范的产物,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的使用规范。
兼容的模块化定义:
可是若是你想作到这一点,必需要额外设置,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的方式,对于不一样的状况作多种处理方式,是很是明智的选择。
最后附上表格一张,仅供参考。
想找我深刻了解的话,能够来这里哟(。・ω・。)