更新:我在下面尝试了Jeff Barczewski的回答,虽然我不再收到以下插件错误,但现在我遇到了一个不同的错误:
Error: TypeError: Cannot read property 'normalize' of undefined
In module tree:
mymodule/core
at Object.<anonymous> (/usr/local/lib/node_modules/requirejs/bin/r.js:1193:35)
更新2: 由于Jeff是正确的Dojo的插件与RequireJS不兼容,我决定转而使用grunt-dojo代替构建dojo。我仍然使用RequireJS作为我自己的代码,并简单地覆盖要忽略的dojo依赖项。
原帖:
我正在尝试使用grunt编译单个JS文件,以降低浏览器需要进行的HTTP请求。由于Dojo 1.9符合AMD标准,我认为我会使用Grunt的requirejs插件来优化我的代码。但是,我在使用Grunt插件和直接使用r.js时收到以下错误:
>> Tracing dependencies for: mymodule/core
>> TypeError: Cannot call method 'createElement' of undefined
>> In module tree:
>> mymodule/core
>> dojo/behavior
>> dojo/query
>> dojo/selector/_loader
{ [Error: TypeError: Cannot call method 'createElement' of undefined
In module tree:
mymodule/core
dojo/behavior
dojo/query
dojo/selector/_loader
at eval (eval at <anonymous> (/Users/EugeneZ/Workspace/presentment/web/js/node_modules/grunt-contrib-requirejs/node_modules/requirejs/bin/r.js:23690:38), <anonymous>:6:24)
]
originalError:
{ [TypeError: Cannot call method 'createElement' of undefined]
moduleTree:
[ 'dojo/selector/_loader',
'dojo/query',
'dojo/behavior',
'mymodule/core' ],
fileName: '/Users/EugeneZ/Workspace/presentment/web/js/dojo_release/dojo/selector/_loader.js' } }
查看_loader
Dojo模块的代码,假设它在浏览器中运行并依赖于document
全局:
var document;
var testDiv = document.createElement("div");
但为什么requirejs不允许这样?我搜索了他们的文档,找不到任何方法来关闭此检查。我假设我误解了某些事情或做错了事,但无法理解。
这是我的Gruntfile.js的requirejs相关部分:
requirejs: {
compile: {
options: {
'baseUrl': './',
'paths': {
'dojo': 'dojo_release/dojo',
'dojox': 'dojo_release/dojox',
'dijit': 'dojo_release/dijit',
'mymodule' : 'core/mymodule',
'osi': 'osi',
'demo': 'demo',
'slick': 'core/slick'
},
'name': 'mymodule/core',
'out': './mymodule.js'
}
}
}
答案 0 :(得分:4)
Dojo有几个与r.js构建器/优化器不兼容的插件。最好的办法是在https://bugs.dojotoolkit.org上记录一个问题,让某人添加必要的插件钩子,以便解决这个问题。
另一种方法是切换到使用dojo构建器,但它似乎不会创建requirejs可以使用的代码,因此您也需要使用它们的加载程序,而不是requirejs。 (dojo builder使用一些专有的?{cache:...}
选项来执行它的依赖,而不仅仅是内联定义,所以我找不到使用requirejs构建和加载的方法。)
另一种解决方法(直到dojo修复插件兼容)如果你想继续使用requirejs(就像我做的那样),你可以从优化中排除使用这些dojo插件的文件,并且只是单独加载那些文件而不是优化的。因此,除了使用这些插件的文件外,您的大多数文件都可以进行优化。它不完美,但它会让你更接近。 Requirejs将以优化的方式加载大多数文件,然后在运行时单独获取那些被排除的文件。
要执行此操作,请为使用错误输出的插件的特定文件添加r.js build.js排除项。因此,在运行构建并获得该错误后,将路径中的文件添加到您的路径中,即。堆栈跟踪中的倒数第二个。
添加到你的r.js构建选项
paths: {
'dojo/query': 'empty:', // this will exclude it from the build
然后再次运行您的构建并重复,直到您获得所有其他错误文件。
当我尝试构建dojo的dgrid时,我最终得到了以下排除:
paths: {
// r.js having issues building these, the plugins are not
// compatible so let them load normally unoptimized
'dgrid/extensions/ColumnHider': 'empty:',
'put-selector/put': 'empty:'
'dojo/i18n': 'empty:',
'dojo/selector/_loader': 'empty:',
'dojo/query': 'empty:',
'dgrid/extensions/ColumnResizer': 'empty:',
'dgrid/List': 'empty:',
'xstyle/css': 'empty:'
您的列表可能会因您使用的内容而异。
然后在运行时让这些文件(及其依赖项)可用,并且requirejs将像在开发中一样加载它们。因此,至少大部分文件将从一个文件进行优化加载,然后这些文件将加载。
注意:要求dojo使插件r.js构建器/优化器兼容是最终的解决方案,所以我们不需要这样做。因此,即使您使用此工作,请为dojo添加一个问题,以便一劳永逸地解决这个问题。提及您最终必须排除的所有文件,以帮助开发人员知道要修复的内容。然后在这里发表评论,让其他人发现+1。