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

Eug*_*neZ 5 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)
Run Code Online (Sandbox Code Playgroud)

更新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' } }
Run Code Online (Sandbox Code Playgroud)

查看_loaderDojo模块的代码,它假设它在浏览器中运行并依赖于document全局:

var document;
var testDiv = document.createElement("div");
Run Code Online (Sandbox Code Playgroud)

但为什么要求不允许这样做?我搜索了他们的文档,找不到任何方法来关闭此检查.我假设我误解了某些事情或做错了什么,但无法理解.

这是我的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'
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Jef*_*ski 4

Dojo 使用的几个插件与 r.js 构建器/优化器不兼容。最好的办法是在https://bugs.dojotoolkit.org上记录问题,让某人添加必要的插件挂钩,以便解决此问题。

另一种方法是切换到使用 dojo 构建器,但它似乎不会创建 requirejs 可以使用的代码,因此您也需要使用它们的加载器,而不是 requirejs。(dojo 构建器使用一些专有的?{cache:...}选项来执行其依赖项,而不仅仅是内联定义,因此我找不到使用 requirejs 构建和加载的方法)。

另一种解决方法(直到 dojo 修复插件兼容)如果您想继续使用 requirejs (就像我一样),您可以从优化中排除使用这些 dojo 插件的文件,而只单独加载这些文件而不进行优化。因此,除了使用这些插件的文件之外,大多数文件都可以进行优化。它并不完美,但它让你更接近。Requirejs 将简单地以优化的方式加载大部分文件,然后在运行时单独获取那些被排除的文件。

为此,请添加到 r.js build.js 排除项,以排除使用出错插件的特定文件。因此,在运行构建后,您会收到该错误,请将使用该插件的文件添加到您的路径中,即。堆栈跟踪中倒数第二个。

因此,添加到您的 r.js 构建选项中

paths: { 
  'dojo/query': 'empty:', // this will exclude it from the build
Run Code Online (Sandbox Code Playgroud)

然后再次运行构建并重复,直到获得所有其他错误文件。

当我尝试构建 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:'
Run Code Online (Sandbox Code Playgroud)

您的列表可能会根据您使用的内容而有所不同。

然后,只需在运行时提供这些文件(及其依赖项),requirejs 就会像在开发中一样加载它们。因此,至少大部分文件将从一个文件加载优化,然后这些文件将在之后加载。

注意:要求 dojo 使插件 r.js 构建器/优化器兼容是最终的解决方案,因此我们不需要执行此 hack。因此,即使您使用此解决方案,也请为 dojo 添加问题,以便一劳永逸地解决此问题。提及您最终必须排除的所有文件,以帮助开发人员知道要修复哪些内容。然后在这里发表评论供其他人+1。