1

我的 Web 应用程序中有几个 JavaScript 文件,这些文件以前是通过<script>标签加载的,按照相对依赖关系的顺序排列。现在我正在通过 require.js 重新组织它们,以便积累和缩小它们以用于生产。

对于初学者,我想简单地将所有文件加载到全局(窗口)上下文中,而无需 AMD 封装:

require([
    'jquery'], function() {
    require([
        'jquery-ui'], function() {
        require([
            'jquery-ui.touch-punch',
            // [...]
        ]);
    });
});

这里的想法是'jquery'定义一个全局(窗口上下文)jQuery变量,'jquery-ui'设置jQuery.ui'jquery-ui.touch-punch'更改jQuery.ui(以获得更好的触摸支持)。

这在按原样运行时效果很好,即没有优化。但是,编译成一个文件并使用RequireJS 优化器缩小后,会出现以下错误:

Uncaught TypeError: Cannot read property 'mouse' of undefined

这发生在试图访问的线路上jQuery.ui.mouse

在浏览器控制台内部,jQuery在窗口上下文中正确设置,但jQuery.ui未定义。但是,手动执行require(['jquery-ui'])确实jQuery.ui按预期设置。

优化后 jQuery UI 的行为似乎有所不同,但我看不出究竟是如何或为什么。我究竟做错了什么?

4

1 回答 1

2

独家新闻

shim使用而不是通过嵌套调用设置非 AMD 模块之间的依赖关系require(实际上并不设置依赖关系)。确保wrapShim: true在您提供的配置中也使用r.js.

解释

您尝试加载的一个或多个模块不是 AMD 模块,但您实际上并未定义非 AMD 模块之间的依赖关系。

当你require像你一样嵌套调用时,你是在强制一些模块在运行时加载的顺序,但这实际上并没有在模块之间建立依赖关系。因此,只要模块未优化,此策略就有效,但优化后可能会失败。

只有两种方式建立依赖关系:

  1. 通过将一组依赖项传递给define调用。此方法由实际为 AMD 规范编写的模块使用。(RequireJS 也支持使用 CommonJS 的方式来请求模块,但是在幕后,它被转换为一个define带有依赖数组的调用。所以它不构成第 3 种方式。)

  2. 通过设置shim哪个列表依赖项。此方法适用于非 AMD 模块。

如果您不设置 a shim,那么优化器可以自由地以它想要的任何顺序订购非 AMD 模块。jquery-ui.touch-punch 可能会出现在优化文件之前jquery-uijquery优化文件中,因为它没有理由不应该出现,然后你就会遇到麻烦。如果您查看此插件的代码,您会发现它不支持 AMD。它只期望 jQuery 和 jQuery UI 存在,如果它们不存在,则会失败。

当您设置 ashim时,您会强制优化文件中非 AMD 模块的顺序。

您需要wrapShim,因为jquery-ui.touch-punch当使用支持 AMD 的 jQuery UI 版本时。否则,jQuery UI 的工厂不会在插件需要它之前运行。

于 2016-12-04T19:37:47.987 回答