使用require.js在onload

时间:2017-01-05 18:26:12

标签: javascript requirejs

我在这里问到了这个问题

load javascript file before onload with requirejs

但那里的解决方案并不符合我的情况,所以我想知道是否有不同的解决方案。我无法使用deps构建并使我的代码成为最后一个,因为我正在制作库/实用程序,而不是应用程序。

我正在研究WebGL-Inspector。它通过包装HTMLCanvasElement.prototype.getContext来工作,如果它看到一个"webgl",那么它会包装上下文并允许你检查它。

WebGL-Inspector以3种模式工作

  1. 作为浏览器扩展程序

  2. 作为加载器+大型编译脚本

  3. 作为加载器+原始源(许多脚本)

  4. 要在上面的模式#2或#3中使用它,只需插入

    即可
    <script src="core/embed.js"></script>
    

    HTML顶部的某个位置。因为它同步加载,所以在它之后的任何脚本之前都会包装HTMLCanvasElement.prototype.getContext

    这最后两种模式主要用于调试/开发WebGL-Inspector本身。特别是模式#3,因为我们可以编辑检查员的代码并立即刷新页面以查看结果,无需构建步骤。

    我正在切换到使用AMD进行所有WebGL-Inspector。我们正在使用这个,因为我们可以使用webpack来制作#2,但仍然遵循相同的开发工作流程,允许我们使用上面的模式#3将脚本标记更改为

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

    问题是这不再有效,因为在加载core/embed.js之前运行与WebGL-Inspector本身无关的任何其他代码,因此在我们有机会将其包装之前调用someCanvas.getContext。< / p>

    我目前的解决方案很遗憾是在我们正在使用的任何演示中延迟1.5秒

    <script src="core/require.js" data-main="core/embed.js"></script>
    <script>
    // wait 1.5 seconds for embed.js to load and pray :(
    window.onload = setTimeout(reallyRunWebGLCode, 1500);
    ...
    </script>
    

    以前的非AMD加载程序没有此异步问题。不知何故,它设法在window.onload触发之前加载60个左右的.js文件。有没有办法让require.js做同样的事情?或者我可能需要编写自己的装载机?

    换句话说,问题在于,现在用户添加了一条<script>行,而对其代码没有进行任何其他更改,并且可以正常运行。完成后,删除单个脚本行。

    切换到AMD / require.js,用户现在需要添加单个脚本并重新编写代码。在我的测试中来自

    window.onload = myapp;
    

    require.config({ baseUrl: "/core" });
    require("./embed", myapp);
    

    虽然很小但是现在当您删除<script>标记时应用程序已损坏,并且必须按原样放回。如果可能的话,我正在努力避免这些变化。事实上,使用原始样式,您甚至不必删除脚本标记,只需在脚本不存在的环境中运行您的应用程序,它将无法加载,您的应用程序将按照正常运行的方式运行如果脚本不存在,它将失败。

    我可以要求更多代码

    if (typeof require === 'function' && typeof define === 'function' and define.amd) {
      require.config({ baseUrl: "/core" });
      require("./embed", myapp);
    } else {
      window.onload = myapp;
    }
    

    但那更加丑陋。我们从添加单个脚本到需要修改您的应用程序。

    实际上,在我正在测试的应用程序中,它变得更糟。它为自己使用不同的加载器。当我运行上面的代码版本时,它失败了,因为在这种情况下需要在window.onload(奇怪)之前运行myapp。我最终不得不这样做

      var tryRunCount = 0;
    
      function tryRunApp() {
        ++tryRunCount;
    
        // check that tryRunApp has been called twice so we know
        // both onload and require have returned
        if (tryRunCount === 2) {
          myApp();
        }
      }
    
      window.onload = tryRunApp;
      require.config({ baseUrl: "/core" });
      require("./embed", tryRunApp);
    

    这是方式比我想要用户做出的更多更改。

0 个答案:

没有答案