有没有办法懒惰地设置RequireJS资源的路径?

时间:2013-04-10 04:47:17

标签: javascript requirejs

所以,我有一个使用requireJS的应用程序。非常高兴。在大多数情况下。

这个应用程序使用Socket.IO。 Socket.IO由nodejs提供,不与主Web服务器在同一端口上运行。

为了解决这个问题,在我们的主js文件中,我们做了类似的事情:

    var hostname = window.location.hostname;
    var socketIoPath = "http://" + hostname + ":3000/socket.io/socket.io";
    requirejs.config({
        baseUrl: "/",
        paths: {
            app           : "scripts/appapp",
            "socket.io"   : socketIoPath
        }
    });

比这更复杂,但你得到了要点。

现在,在交互模式下,这可以游动。

当我们尝试使用r.js来编译时,丑陋开始(技术上我们使用grunt来运行r.js,但除了这一点之外)。

在r.js的配置中,我们为socket.io设置了一个空路径(以避免它无法拉入),我们将主文件设置为mainConfigFile。

编译器对此大吼大叫,说:

Running "requirejs:dist" (requirejs) task
>> Error: Error: The config in mainConfigFile /…/client.js cannot be used because it cannot be evaluated correctly while running in the optimizer. Try only using a config that is also valid JSON, or do not use mainConfigFile and instead copy the config values needed into a build file or command line arguments given to the optimizer.
>>     at Function.build.createConfig (/…/r.js:23636:23)

现在,我可以说,这是因为我正在使用变量来设置“socket.io”的路径。如果我把它拿出来,需要运行很好,但我不能从服务器运行原始。如果我离开它,我的调试服务器很高兴,但构建中断了。

有没有办法可以在运行时懒惰地分配“socket.io”的路径,这样就不必在那时进入requirejs.config()方法了?

1 个答案:

答案 0 :(得分:2)

编辑:对此进行了一些广泛的研究。结果如下。

使用RequireJS从CDN加载是可能的。但是,如果您使用较小的杏仁加载程序,it's not possible

这为您提供了两个选项:

  1. 在构建中使用杏仁以及文件的本地副本。
  2. 使用完整的require.js加载程序并尝试使用CDN。
  3. 仅为该资源使用<script>标记。
  4. 我说尝试#2,因为有一些警告。您需要在HTML中添加require.js,并为您的构建文件添加data-main属性。但是如果你这样做,requiredefine将是全局函数,允许用户require任何内部模块并使用它们。如果您对此感到满意,则需要遵循构建配置中的"empty: scheme"(但不要在主配置中)。

    但事实仍然是你现在有另一个HTTP请求。如果您只想要一个包含require.js加载程序的内置文件,则需要optimize for only one file

    现在,如果您想避免用户能够require您的模块,那么您必须在构建中执行wrap:true之类的操作。但据我所知,一旦你的模块从CDN下来,如果它是AMD,它将寻找一个全局define函数来注册自己,并且这将不存在,因为它现在包含在闭合。

    我从这一切中汲取的教训:为您的构建内嵌资源。这说得通。您减少HTTP请求,缩小所有内容并获得gzip压缩。您不会将模块暴露给世界,一切都变得简单多了。如果您正确缓存资源,您甚至不必担心它。

    但是由于socket.io的新版本不喜欢AMD,所以我就是这样做的。确保在requirejs之前包含socket.io <script>标记。然后创建一个名为socket.io的requirejs模块,其中包含以下内容:

    define([], function () {
      var io = window.io;
      window.io = null;
    
      return io;
    });
    

    如此设置路径:'socket.io': 'core/socket.io'或您想要的任何位置。

    并且正常需要它!构建工作正常。


    原始答案

    您是否可以使用RequireJS API中指定的path config fallbacks?也许你可以在本地保存文件作为后备,这样你的构建就可以了。

    socket.io GitHub存储库specifies,您可以使用socket.io-client软件包的dist /目录中的文件为客户端提供服务。