Requirejs无法编译我的dojo依赖模块

时间:2013-12-09 21:43:53

标签: javascript dojo requirejs

更新:我在下面尝试了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'
            }
        }
    }

1 个答案:

答案 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。