Requirejs无法编译我的dojo依赖模块 [英] Requirejs can't compile my dojo-dependent module

查看:151
本文介绍了Requirejs无法编译我的dojo依赖模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我在下面尝试了Jeff Barczewski的回答,虽然我不再在插件中收到错误,但我现在收到一个不同的错误:

 错误:TypeError:无法读取未定义的属性'normalize'
在模块树中:
mymodule / core

在对象<匿名> (/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时,我收到以下错误:

 >> ;跟踪依赖关系:mymodule / core 
>> TypeError:无法调用未定义的方法'createElement
>>在模块树中:
>> mymodule / core
>> dojo / behavior
>> dojo / query
>> dojo / selector / _loader
{[错误:TypeError:不能调用方法'createElement'未定义
在模块树中:
mymodule / core
dojo / behavior
dojo / query
dojo / selector / _loader
$ b at eval(eval at< anonymous>(/ Users / EugeneZ / Workspace / presentment / web / js / node_modules / grunt-contrib-requirejs /
]
原始错误:
{[TypeError:无法调用方法'createElement'为未定义]
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 global:

  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',
' :'core / slick'
},
'name':'mymodule / core',
'out':'./mymodule.js'
}

}


解决方案

Dojo有几个与r.js构建器/优化器不兼容的插件。最好的办法是在 https://bugs.dojotoolkit.org 上记录一个问题,让有人添加必要的插件钩子,所以这可以解决。



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



另一个工作(直到dojo修复插件才能兼容)如果你想留在requirejs(像我这样做),你可以排除使用的文件这些dojo插件来自优化,只是这些文件单独加载未优化。因此,除了使用这些插件的文件之外,大多数文件都可以进行优化。它不完美,但它让你更近。 Requirejs将以优化的方式简单地加载大部分文件,然后在运行时单独提取排除的文件。



为此,添加到您的r.js build.js排除特定文件,使用插件出现错误。所以在运行构建之后,你得到这个错误,添加到你的路径使用该插件的文件,即。在堆栈跟踪中的第二个。



所以添加到你的r.js构建选项

  {
'dojo / query':'empty:',//这将从build

然后再次运行你的构建,并重复一遍,直到你收到所有其他文件的错误。



当我试图构建dojo的dgrid时,我结束了以下排除:

 路径:{
// r.js有问题构建这些,插件不是
// compatible,所以让它们正常加载未优化的
'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:'
/ pre>

您的列表可能会有所不同o n你正在使用什么。



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



注意:要求dojo使插件r.js builder / optimizer兼容是最终的解决方案,所以我们不需要这样做。所以即使你使用这个工作,请为dojo添加一个问题,这样一来可以解决。提及您最终不得不排除的所有文件,以帮助开发人员了解要解决的问题。然后在这里发表评论给他人+1。


UPDATE: I tried Jeff Barczewski's answer below, and though I no longer get the error below for plugins, I am now getting a different error:

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)

UPDATE 2: Since Jeff is correct that Dojo's plugins are not compatible with RequireJS, I decided to switch to using grunt-dojo instead for building dojo. I still use RequireJS for my own code and simply override the dojo dependencies to be ignored.

Original Post:

I'm trying to use grunt to compile a single JS file to lower the amount of HTTP requests browsers need to make. Since Dojo 1.9 is AMD-compliant, I figured I'd use Grunt's requirejs plugin to optimize my code. However, I am receiving the following error, both when using the Grunt plugin and when using r.js directly:

>> 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' } }

Looking at the code for the _loader Dojo module, it's assuming it's running in a browser and relying on the document global:

var document;
var testDiv = document.createElement("div");

But why does requirejs not allow this? I've searched their documentation and can't find any way to turn this check off. I'm assuming I'm misunderstanding something or doing something wrong, but can't figure it out.

Here is the requirejs-relevant portion of my Gruntfile.js:

    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'
            }
        }
    }

解决方案

Dojo has several plugins that it uses that are not compatible with the r.js builder/optimizer. The best thing to do is to log an issue on https://bugs.dojotoolkit.org to have someone add the necessary plugin hooks so this can be resolved.

An alternative is to switch over to using the dojo builder, but it doesn't appear to create code that requirejs can use, so you would need to use their loader too, not requirejs. (dojo builder uses some proprietary? {cache:...} option for doing its dependencies rather than just inlining defines, so I could not find a way to build and load with requirejs).

Another work around (until dojo fixes the plugins to be compatible) if you want to stay with requirejs (like I did), you can exclude files that use these dojo plugins from the optimization and just have those files loaded separately unoptimized. So most of your files can be optimized except for ones using these plugins. Its not perfect but it gets you closer. Requirejs will simply load most of the files in optimized fashion and then just fetch those excluded ones individually at runtime.

To do this, add to your r.js build.js exclusions for specific files that use plugins which error out. So after running the build and you get that error, add to your paths the file that is using the plugin, ie. the second to last in the stack trace.

So add to your r.js build options

paths: { 
  'dojo/query': 'empty:', // this will exclude it from the build

Then run your build again and repeat until you have gotten all the other files that error.

When I was trying to build dojo's dgrid, I ended up with the following exclusions:

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:'

Your list may vary based on what you are using.

Then just have these files (and their dependencies) available when running and requirejs will load them as it does in development. So at least the majority of your files will be loaded optimized from one file, then these will load after.

Note: Asking dojo to make the plugins r.js builder/optimizer compatible is the ultimate solution so we wouldn't need to do this hack. So even if you use this work around, please add an issue for dojo so this can get resolved once and for all. Mention all of the files that you ended up having to exclude to help the developers know what to fix. Then post a comment here for others to +1.

这篇关于Requirejs无法编译我的dojo依赖模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆