如何正确地引入Promise的polyfill

前端发展到今天,很多新特性并不能直接在浏览器中使用,尤其是在移动端,所以我们经常会需要引入polyfill。那么问题来了,我们应该如何优雅地引入polyfill呢?

这里我提到的优雅包括以下几方面:

  • 对开发者友好
  • 不与标准冲突
  • 不重复引入多余的代码

下面从应用(application)库(library)的角度分别来探讨一下引入polyfill的方案。

应用

应用中引入一个polyfill其实不需要考虑太多,因为这里完全是我们的地盘,不用担心对其他代码造成副作用。那么最直接的方法就是引入标准中存在而实际中不存在的全局变量,以Promise为例:

// 直接从core-js引入全局的polyfill
import 'core-js/fn/promise';

当我们使用了babel的情况下,如果开启了babel-plugin-transform-runtime,我们会发现,代码中用到Promise的地方都被babel进行了转换,自动转换成了babel-runtime/core-js/promise,实际上就是一个不污染全局的core-js的polyfill,相当于core-js/library/fn/promise。通过分析代码,我们会发现,core-js/library/fn/promisecore-js/fn/promise引入了两套大同小异的代码,一套不会污染全局,一套会直接挂载到window上。这种引入重复代码的行为显然是不优雅的。
考虑到良好的开发体验,直接使用Promise让babel转换更加自然,不用每次都去引入,显然我们更愿意接受babel-plugin-transform-runtime的polyfill。
但是有些第三方库可能也会依赖Promise,他们却不会被babel处理,这时就需要从window上获取,所以还是需要挂载到window上,而且这样也是符合ES6标准的。
一个简短的写法如下:

// 如果开启了babel-plugin-transform-runtime,则
window.Promise = window.Promise || Promise;

第三方库通常不应该去直接依赖其他公共库,这样有可能会导致重复的依赖或者不同版本间的冲突。比如Promise可以有不同的实现,我们应该交由应用代码去选择,比如移动端倾向于选择更小的实现。
所以在库里面,我们只要按照ES6规范去使用Promise就好了,在编译的时候也不需要进行特殊处理。然后在文档里面告诉用户:

我们是依赖Promise的,请自行配置polyfill喔。

你可能感兴趣的:(如何正确地引入Promise的polyfill)