【问题标题】:Preload polyfill libraries using requirejs使用 requirejs 预加载 polyfill 库
【发布时间】:2014-08-22 18:22:33
【问题描述】:

我正在使用requirejs 创建一个wirejs 应用程序。对于 IE 8,我使用的是 polyfill:cujo/poly js 库,并要求在加载 wirejs 之前预加载此库。

如果我使用 curl 作为 AMD 加载程序,根据文档,我有以下可用选项:

curl({ preloads: [ "poly" ] });

对我有用的是:

// in index.html

<script data-main="js/app" src="js/lib/require.js"></script>

// in js/app.js

define(function(){
   // set configuration options
   requirejs.config({// set config with paths});

   // require the library and HOPE it will load before
   // everything else!
   require(['poly']);

});

This document 建议为此使用 shim 配置。但是,我一直无法弄清楚如何。我尝试过的一些事情:

// DID NOT WORK!!
requirejs.config({

....
"shim": {
   "poly": {
     "exports": "poly"
    }
 }
});

有没有更好的方法来解决这个问题?

任何帮助表示赞赏!...感谢您的时间!

【问题讨论】:

  • 我不确定为什么 James 取消了对确保首先加载某些模块的支持。如果有办法使用 shim 配置来确保首先加载全局脚本,那么描述如何浏览 poly.js 的这个 github 问题可能会有所帮助:github.com/cujojs/poly/issues/28#issuecomment-29720704

标签: requirejs polyfills wirejs


【解决方案1】:

我确实将 RequireJS 与 polyfill 一起使用,但我不使用 RequireJS 来加载它们。 polyfill 的目标是使缺少功能 X 的浏览器看起来好像实际上具有功能 X。我更喜欢在其中 all 我运行的代码的设置(除了 polyfill它们自己)运行已加载的 polyfill,因此无论使用什么浏览器运行代码,代码都可以使用相同的可用功能集运行。所以我也希望在 RequireJS 之前加载我的 polyfill。

但是如果我们忽略这个偏好,是否可以使用 RequireJS 来加载 polyfill?是的,但 RequireJS 不会让它变得容易。没有简单的方法可以告诉 RequireJS“必须在加载 其他任何东西之前加载这段代码”,这就是你想要的 polyfills。您需要做的是手动调用 require 以便首先加载您的 polyfill。您的 index.html 可能类似于:

<script>
    require = {
       // Your config.
       //
       // Setting a global require before loading RequireJS is one way to give it
       // a config.
    };
</script>
<script src="js/lib/require.js"></script>
<script>
    // No data-main above...
    //
    // This double require ensures that the polyfills are loaded first.
    require(["poly"], function () {
        require(["js/app"]);
    });
</script>

js/app.js 变为:

define(function(){
    // whatever...
});

在一个可能有多个入口点而不是js/app 的大型应用程序中,每次要从 RequireJS 模块外部加载模块时,都必须使用上述双重要求,以确保首先加载 polyfill .

【讨论】:

  • 是的,这可以正常工作。不幸的是,任何需要首先加载 polyfill 的设置都比将 polyfill 嵌入到应用程序包中要慢。 Fwiw,使用带有 async="false" 的多个脚本标签会比使用嵌入式 require() 调用更快,因为 requirejs 必须在开始加载 js/app 之前完成加载 poly。
  • 谢谢大家!! QQ:当我使用cujo/polydeps require.config here 选项时,我得到了一些“成功”。所以我的require-config 看起来像这样:{ // paths...// packages...// , 'deps': ['poly/all'] }。我在 IE8 中运行了几次,它似乎已经预加载了 polyfill 库。你们认为这是一个可行的选择吗?
  • @unscriptable 你说:“任何需要首先加载 polyfill 的设置都比将 polyfill 嵌入到应用程序包中要慢。”当有人提供硬数据显示性能差异显着时,我会为此失眠。
  • @unscriptable 您还说:“Fwiw,使用带有 async="false" 的多个脚本标签会比使用嵌入式 require() 调用更快,因为 requirejs 必须完成加载poly 在开始加载 js/app 之前。”但是您之前谈到了“将 polyfill 嵌入到应用程序包中”。如果 polyfill 包含在包中,则应用程序将在请求 polyfill 时立即加载,因为它们位于同一个包中。第二个require 会为整个操作增加一点时间,因为应用程序已经被加载了。
  • @Vikram 您提供给deps 的模块只是计划立即加载。根本无法保证它们何时执行。它们可以在您的应用程序开始执行后执行。 (来自the doc:“它不会阻止任何其他 require() 调用开始对模块的请求 [...]”)
【解决方案2】:

我遇到了同样的问题,我的解决方案是让 Require.js 为我加载 polyfills 作为依赖项。你可以在this gist 中看到我是如何结合Conditioner.js 解决它的,但是没有它的解决方案是一样的。

我选择了检测加载 polyfill 的功能,因此较新的浏览器不会发出不必要的请求。特征检测使这个特定的解决方案更胜一筹。

在你的index.html:

<script src="/js/require.js" data-main="/js/main"></script>

在文件/js/main.js

var _polyfills = [];
if (!('classList' in document.documentElement)) {
    _polyfills.push('polyfills/classList');
}
// ... more feature detects & polyfills ...

require(['bootstrap'].concat(_polyfills), function(bootstrap) {
    bootstrap.run(); // Bootstrap your app here!
});

【讨论】:

  • 假设bootstrap 需要模块foo(这是一个第三方库)和foo 需要classList。在加载classList 之前如何防止foo 加载?您在答案中显示的内容并不能阻止此问题。另外,鉴于r.js 无法遵循计算的依赖关系,您如何在此类代码上运行优化器以使其在多个平台上运行?
猜你喜欢
  • 1970-01-01
  • 2014-10-26
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多