libraryTarget的几种选择咱们来好好分析

很久没写库了,发现时代变了node

这一切的原由都是由于那只pm,整个一个奇奇怪怪的需求,而后发现须要写库了,就在我流利的初始化项目时,忽然脑抽风的发现,library配置貌似不太对,libraryTarget配置貌似也不太对,因此仍是停下来吧,好好分析回顾一下,阿西吧。webpack

先来回顾一下,library是指定义一个全局使用的名称变量,libraryTarget是指设置library的暴露方式,是commonjs、commonjs二、umd仍是this、var等。web

变量定义:浏览器

  • libraryTarget:“assign”,暴露一个未定义的library设置的变量。在node环境不支持。
  • libraryTarget:“var”,暴露一个用var 定义的library设置的变量。在node环境下不支持。

这两个属性,都是在全局建立一个变量,只有定义与未定义的区别,而且并不能在nodejs中得的支持,而且存在变量冲突的可能性。模块化

观察一下libraryTarget:“assign” or “var”产出的代码,只是建立了一个library里设置的变量,而后经过webpack的方法作一个导出。函数

对象定义:ui

  • libraryTarget:“window”,在window对象上定一个library设置的变量。在node环境下不支持。
  • libraryTarget:“global”,在global对象上定义一个library设置的变量。受target属性影响,当target为默认值web时,会在window上注册,若是你想在global上注册,必须修改target为node。
  • libraryTarget:“this”,在当前this对象上定义一个library设置的变量,若是this是window,就在window。在node的环境中,若是没指定require赋值的变量,并不会在指向global。

这三个属性的特征都是在公共对象上export出你的方法函数。特色无非是减小了变量冲突的可能性,可是依旧没有解决问题,只有global模式支持在node环境中,还必须设置target为node否则也是不支持的。this

观察一下libraryTarget:“window” or “global” or “this”产出的代码,在相应的libraryTarget设置的对象上,建立一个library设置的变量,而后根据webpack的方法作一个导出。global有一个注意点,那就是target配置。若是没有写那默认是在window对象上注册。cdn

模块定义:对象

  • libraryTarget:“commonjs”,在export对象上定义library设置的变量。在node中支持,浏览器中不支持。
  • libraryTarget:“commonjs2”,直接用module.export导出export,会忽略library设置的变量。在node中支持,在浏览器中不支持。
  • libraryTarget:“amd”,在define方法上定义library设置的变量,不能用script直接引用,必须经过第三方模块RequireJS来时用

这两个属性,是符合模块化规范的产物,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的使用规范。

兼容的模块化定义:

  • libraryTarget:“umd”,该方案支持commonjs、commonjs二、amd,能够在浏览器、node中通用。

可是若是你想作到这一点,必需要额外设置,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的方式,对于不一样的状况作多种处理方式,是很是明智的选择。

最后附上表格一张,仅供参考。


想找我深刻了解的话,能够来这里哟(。・ω・。)

相关文章
相关标签/搜索