简体   繁体   English

使用requirejs&r.js优化器时无法加载jQuery插件

[英]Unable to load jQuery plugins when using requirejs & r.js optimizer

I'm having a bit of trouble with my the requirejs optimizer. 我的requirejs优化器遇到了一些麻烦。 After I run the optimizer, I get a few error messages in my build/compiled file. 运行优化器后,我在构建/编译文件中收到一些错误消息。 When running my web application without the optimize step I do not have any errors. 在没有优化步骤的情况下运行我的Web应用程序时,我没有任何错误。

This is my client.js file (contains config) (coffeescript) 这是我的client.js文件(包含配置)(coffeescript)

requirejs.config
  baseUrl: '/source/'
  paths:
    text:                 'lib/text'
    io:                   'lib/socket.io'
    underscore:           'lib/underscore'
    backbone:             'lib/backbone'
    jquery:               'lib/jquery'
#    almond:               'lib/almond'
    bootstrap:            'lib/bootstrap'
    bootstrapFileUpload:  'lib/bootstrap-fileupload'
    jqueryUniform:        'lib/jquery.uniform'
    jqueryBrowser:        'lib/jquery.browser'
    datatables:           'lib/jquery.dataTables'
    datatables_bootstrap: 'lib/DT_bootstrap'
  shim:
    io:
      exports: 'io'
    jquery:
      exports: 'jQuery'
    jqueryBrowser:
      deps:    ['jquery']
    jqueryUniform:
      deps:    ['jqueryBrowser', 'jquery']
    underscore:
      exports: '_'
    backbone:
      deps:    ['underscore', 'jquery']
      exports: 'Backbone'
    datatables_bootstrap:
      deps:    ['jquery', 'datatables']
    datatables:
      deps:    ['jquery']


require ['routers/router', 'backbone'], (Router, Backbone) ->
  MainRouter = new Router()
  Backbone.history.start()

And here is my config for the optimizer. 这是我的优化器配置。 I run the optimizer from nodejs after requiring 'requirejs' as a module. 在将'requirejs'作为模块后,我从nodejs运行优化器。

  config =
    baseUrl: __dirname + '/../client/source'
    name:    'lib/almond'
    include: './client'
    optimize: 'none'
    out:     __dirname + '/../client/' + hash + '.js'
    paths:
      text:                 'lib/text'
      io:                   'lib/socket.io'
      underscore:           'lib/underscore'
      backbone:             'lib/backbone'
      jquery:               'lib/jquery'
      bootstrap:            'lib/bootstrap'
      bootstrapFileUpload:  'lib/bootstrap-fileupload'
      jqueryUniform:        'lib/jquery.uniform'
      jqueryBrowser:        'lib/jquery.browser'
      datatables:           'lib/jquery.dataTables'
      datatables_bootstrap: 'lib/DT_bootstrap'
    shim:
      bootstrap:
        exports: 'bootstrap'
      bootstrapFileUpload:
        exports: 'bootstrapUpload'
      io:
        exports: 'io'
      jquery:
        exports: 'jQuery'
      jqueryBrowser:
        deps:    ['jquery']
      jqueryUniform:
        deps:    ['jqueryBrowser', 'jquery']
      underscore:
        exports: '_'
      backbone:
        deps:    ['underscore', 'jquery']
        exports: 'Backbone'
      datatables:
        deps:    ['jquery']
      datatables_bootstrap:
        deps:    ['jquery', 'datatables']



  requirejs.optimize config, (buildResponse) ->
    js = true
    if js && css
      require './server'
  , (err) ->
    console.log 'requirejs err'
    console.log err

The specific error I'm seeing in chrome is: "Uncaught TypeError: Cannot read property 'defaults' of undefined" 我在chrome中看到的具体错误是:“未捕获的TypeError:无法读取未定义的属性'默认值'”

Which correlates to this snippet: 这与此代码段相关:

/* Set the defaults for DataTables initialisation */
$.extend( true, $.fn.dataTable.defaults, {

Any idea what might be going wrong? 知道可能出了什么问题吗? Thanks! 谢谢!

I encountered the same issue. 我遇到了同样的问题。 I think the reason this error occurs is because DT_bootstrap.js is not a AMD module while it depends on the side effects of one. 我认为发生此错误的原因是因为DT_bootstrap.js不是AMD模块,而是取决于一个的副作用。 In this case jquery.dataTables.js . 在这种情况下, jquery.dataTables.js

When RequireJS optimizer combines all the modules you reference into one big JS file, the raw DT_bootstrap.js is somewhere in the middle of it, some place after jquery.dataTables.js . 当RequireJS优化器将您引用的所有模块组合到一个大型JS文件中时,原始DT_bootstrap.js位于其中间的某个位置,一些jquery.dataTables.js之后。 The problem is that DT_bootstrap.js is evaluated immediately when your combined js file is loaded. 问题是在加载组合的js文件时会立即评估DT_bootstrap.js It wants $.fn.dataTable to be defined when it encounters the line: 它希望在遇到该行时定义$.fn.dataTable

$.extend( true, $.fn.dataTable.defaults, {

Since jquery.dataTables.js is a AMD module it has been compiled but not evaluated yet. 由于jquery.dataTables.js是一个AMD模块,因此它已经编译但尚未评估。 Only in later code where it is required as a dependency will it be evaluated, and only then will it define $.fn.dataTable . 只有在需要作为依赖项的后续代码中才会对其进行评估,然后才会定义$.fn.dataTable

I worked around this by wrapping 'DT_bootstrap.js' in a AMD module definition, like is done here: https://github.com/amdjs/backbone/blob/master/backbone.js#L8-L24 我通过在AMD模块定义中包装'DT_bootstrap.js'来解决这个问题,就像在这里完成的那样: https//github.com/amdjs/backbone/blob/master/backbone.js#L8-L24

For example: 例如:

(function(root, factory) {
  // Set up DT_bootstrap appropriately for the environment.
  if (typeof define === 'function' && define.amd) {
    // AMD
    define(['jquery', 'datatables', 'bootstrap'], function($) {
      factory($);
    });
  } else {
    // Browser globals
    factory(root.jQuery);
  }
}(this, function($) {
    // <--- original DT_bootstrap.js goes here 
}));

It solved the issue for me. 它为我解决了这个问题。

Peter is almost correct. 彼得几乎是正确的。 The only thing he missed was that the defines must match Casey's config. 他唯一遗漏的是定义必须与Casey的配置相匹配。 So in the above answer, instead of: 所以在上面的答案中,而不是:

define(['jquery', 'dataTable', 'bootstrap'], function($) ...

it would need to be: 它需要是:

define(['jquery', 'datatables', 'bootstrap'], function($) ...

Otherwise require js will look for the file dataTable.js and not the one it needs to retrieve. 否则需要js查找文件dataTable.js而不是它需要检索的文件。

由于require 2.1.11 的wrapShim选项可以处理这个问题,因此可以保留原始的源文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM