我的 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 optimizer 缩小之后,出现以下错误:
Uncaught TypeError: Cannot read property 'mouse' of undefined
这发生在试图访问 jQuery.ui.mouse
的线路上.
在浏览器控制台内,jQuery
在窗口上下文中正确设置,但是 jQuery.ui
未定义。
但是,手动执行 require(['jquery-ui'])
确实设置了 jQuery.ui
正如预期的那样。
优化后 jQuery UI 的行为似乎有所不同,但我看不出具体情况或原因。我做错了什么?
最佳答案
独家新闻
使用 shim
设置非 AMD 模块之间的依赖关系,而不是通过嵌套的 require
调用(实际上不设置依赖关系)。还要确保在您提供的配置中使用 wrapShim: true
r.js
。
说明
您尝试加载的一个或多个模块不是 AMD 模块,但您实际上并未定义非 AMD 模块之间的依赖关系。
当您嵌套 require
调用时,您会强制执行某些模块在运行时加载的顺序,但这实际上并没有在模块之间建立依赖关系。因此,只要模块未优化,此策略就有效,但可能在优化后失败。
建立依赖关系只有两种方式:
通过将一组依赖项传递给
define
调用。实际为 AMD 规范编写的模块使用此方法。 (RequireJS 也支持使用 CommonJS 方式来请求模块,但在幕后,它被转换为带有依赖数组的define
调用。所以它不构成第三种方式。)通过设置列出依赖项的
shim
。此方法适用于非 AMD 模块。
如果您没有设置shim
,那么优化器可以自由地按照它想要的顺序对非AMD 模块进行排序。 jquery-ui.touch-punch
可以出现在优化文件中的jquery-ui
和jquery
之前,因为有没有理由不应该,然后你会遇到麻烦。如果您查看此插件的代码,您会发现它不是 AMD 感知的。它只是期望 jQuery 和 jQuery UI 存在,如果它们不存在,就会失败。
当您设置shim
时,您会强制优化文件中非 AMD 模块的顺序。
您需要 wrapShim
因为 jquery-ui.touch-punch
在使用 AMD 感知版本的 jQuery UI 时。否则,jQuery UI 的工厂将不会在插件需要它之前运行。
关于javascript - requirejs 优化后 jQuery.ui undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40958373/