如何在Angular中模块化polyfill?

时间:2014-07-15 23:26:37

标签: angularjs

我想在AngularJS应用程序中使用各种polyfill / shims。

例如,IE9及以下版本不支持classList

我在我的应用中尝试了两种定义polyfill的方法:

首先,只需将所有polyfill放在我的app.js页面的顶部,其中所有其他模块都已定义和配置。

其次,我试过这个:

angular.module('polyfills',[]);
angular.module('polyfills')
    .config([function() {
        // all polyfills in here
    }]);

两种选择都有效。但是,这两种选择对我来说都有点奇怪。直觉上,使用.config感觉就像我应该坚持配置提供程序,拦截器等内容。看起来这可能是一个已经在过去已经解决的问题,我感觉某种最好的结果就是练习。

有更好的方法吗?

1 个答案:

答案 0 :(得分:4)

不要将您的polyfill放在角度模块中,这很奇怪,而不是你想要的。你想要的是每个浏览器中的js实现看起来都一样,所以在任何其他js资源之前加载你的polyfill。创建一个js文件(如果您希望每个polyfill在其自己的文件中更多)包含您的polyfill,并在任何其他js文件之前加载到脚本标记中。您的polyfill也应该在IIFE内。

这是Array.from的一个示例polyfill(这是一个非常简单的polyfill用于演示目的):

阵列从-polyfill.js

(function() {
  'use strict';
  Object.defineProperty(Array, 'from', {
    configurable: false,
    enumerable: false,
    value: function (object) {
        'use strict';
        return [].slice.call(object);
    }
    });
})();

然后在任何其他js文件之前,将以下标记放在index.html(或任何你称之为顶级模板)的中。是的,甚至在角度或自举资源之前。

<script src="path/to/array-from-polyfill.js"></script>

最后两项注意事项。首先,始终使用Object.defineProperty,并将'enumerable'设置为false。除非您想要某种方法迭代对象的属性以获取您的polyfill,否则这是非常的。这意味着你必须摆弄MDN的polyfills,但这没关系。无论如何,您应该知道如何绕过defineProperty。

其次,我建议您在每个浏览器中加载polyfill,即使浏览器已经具有该功能。基本上,您执行的代码应尽可能在任何地方都相同。在一个特定浏览器中出现错误没有什么比这更令人恼火了,因为使用您的polyfill是(或不是这样)。这不是一个普遍的事实,所以对你感觉是对的。

不要忘记确保您的polyfill也在测试环境中加载,并定期检查是否可以退回polyfill。