注意: 这是我想要发布给别人使用的第一个模块,因为我觉得它非常有用。它是TypeScript的类型化数据序列化引擎。我对如何在这里做的事情感到有些迷茫,我需要一个明确的答案。所以,谢谢你今天跳进去,让我们来看看......
我创建了一个使用ES6集合类型npm
和Set
的{{1}}模块。这些集合类型是:
这些类型的内部使用并没有太大的麻烦,因为据我所知,我可以通过Map
简单地依赖它们,并在我的源代码中导入它们;然后我就定了,他们将永远在那里。
另一方面,如果我这样做,我理解这些导入会覆盖原生 Map / Set对象(如果可用),并与之冲突我依赖的类型检测(或者这些导入会在可用时产生本地对象吗?)。
关于上面提到的类型检测...最好通过示例进行演示 - 如果用户要在我的模块中使用package.json
对象,这就是它的方式完成:
Map
这就是在我的模块中 中检测和处理地图的方式:
// Consumer code.
class MapContainer {
@JsonMember
mapValues: Map<number, string>;
}
现在很明显这会导致冲突。反过来也是一个问题:如果用户将// Internal module code.
// Just for the sake of clarity: 'sourceValue === new MapContainer().mapValues'
if (sourceValue.constructor === Map) {
// Handle 'sourceValue' as a map object...
}
映射/设置为模块而不是使用本机可用实现,则模块的内部代码将无法识别。
在这种情况下,我该如何定义依赖项?
import
? (除了在文档/限制中提及之外,我如何确保模块的用户也这样做?)require('es6-map/implement')
和Map
通过我的源中的一些别名,例如Set
和__Map
,并使用基于字符串的“类名”检测而不是比较构造函数引用? (这看起来很脏)答案 0 :(得分:1)
首先,根据定义,无条件应用的polyfill实际上不是polyfill,而是hack(例如zone.js)。表现良好的polyfill将使用特征检测,并且只有在尚未存在的情况下才添加全局。
你基本上有三个选择:
您可以使用导出其功能的polyfill而不是扩充全局。这种技术称为ponyfilling。它有点随意,因为它没有真正完成polyfilling的功能 - 它不提供原生体验。但是,这样做的好处是,您可以正确地依赖于您选择的实现,并且您的用户可以依赖于不同的实现,而这两者不会产生干扰。 这种方法看起来像
import Map from 'es6-map'; // pony pure
如您所述,您可以选择不提交特定的polyfill,而只是记录您的库需要符合ES2015的Set
和Map
功能。然后,您的用户可以从各种填充物中进行选择。这样做的好处是,如果用户想要使用不同的polyfill,他们可以在不增加代码大小的情况下这样做,这对于针对浏览器的项目非常重要。此选项还允许您自己的代码利用可用的本机实现,而选项1则无法实现。
另一种方法是自己简单地填充它。就您自己的代码的结构方式而言,这是最简单的选择,但也最有可能导致与消费者及其依赖关系的冲突。与选项2一样,这具有在可用的情况下使用本机实现的优点。然而,存在缺点。无论用户是否需要,您都将强制用户支付使用此功能的费用。用户可能不知道您的库是导致polyfilled Map
在其代码中可用的原因,并且可能会隐含地依赖于它。相对于其他依赖项,库的加载顺序可能会导致非常奇怪且难以检测到错误。这种方法看起来像
import 'es6-map/implement'; // mutate the global
那么与您的具体用例有何关系?大多数情况适用于任何依赖于可能需要填充的功能的库,但正如您所建议的那样,特定相关的部分与别名相关。 没有必要求助于字符串比较。
相反,如果您要导入Map
而不是填充它(选项1.使用ponyfill方法),则无法将您在实施中导入的Map
与从属关系中捕获的值进行比较。代码,因为它将是一个不同的引用,结果通常是false
,肯定永远不会可靠。此外,如果您希望它在内置Map
支持,polyfilled或native的环境中工作,则Map
中的sourceValue.constructor === Map
标识符需要引用全局Map
in无论那是什么环境。
我建议使用选项1,因为它提供了最大的兼容性,并允许您正确指定依赖项。
这意味着在{<1}}中导入Map
,如
import Map from 'es6-map';
将创建一个本地。如果您需要在同时与全局Map
交互的模块中使用它,那么您需要在别名下导入它,正如您已经考虑过的那样。
值得注意的是
sourceValue.constructor === Map
如果全局没有Map
,将会进入某些环境,因此您需要使用类似
的内容检查typeof Map !== 'undefined' && sourceValue.constructor === Map
安全。
无关紧要,请将开头{
放在与需要的相同的行上。这在JavaScript中很重要。