backbone.localStorage,require.js,"Uncaught TypeError:undefined不是函数"

P. *_*ore 2 local-storage requirejs backbone.js

我在http://kilon.org/blog/2012/08/build-backbone-apps-using-requirejs/上关注Uzi Kilon的BackboneJS/RequireJS/backbone.LocalStorage示例.

当我git clone https://github.com/uzikilon/Todos工作得很好 - 但它使用旧版本的backbone.localstorage.但是,如果我lib/backbone.localStorage用新版本替换http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.0/backbone.localStorage-min,那么我在这里得到"Uncaught TypeError:undefined is not function":https://github.com/uzikilon/Todos/blob/master/js/models/Todo.js#L3 - 为什么?我认为这与http://requirejs.org/docs/api.html#config-shim上的棘手细节有关或可能与此有关:http://blog.mostlystatic.com/2013/01/backbone-localstorage -uncaught.html.

require.config({
  baseUrl: "./js/",
  paths: {
    jquery: 'lib/jquery-1.8.2',
    underscore: 'lib/underscore-1.4.2',
    backbone: 'lib/backbone-0.9.2',
//    'backbone.localStorage': 'lib/backbone.localStorage'
    'backbone.localStorage': 'http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.0/backbone.localStorage-min'

  },
  shim: {
    underscore: {
      exports: "_"
    },
    backbone: {
      deps: ['underscore', 'jquery'],
      exports: 'Backbone'
    },
    'backbone.localStorage': {
      deps: ['backbone'],
      exports: 'Backbone'
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

Sim*_*ith 9

问题在于最新的Backbone localStorage是AMD兼容的,因为该示例中的版本不是,因此是shim配置.

修复

删除shimbackbone.localStorage 的配置,您将不需要它:

'backbone.localStorage': {
  deps: ['backbone'],
  exports: 'Backbone'
}
Run Code Online (Sandbox Code Playgroud)

然后,在Todo.js更改定义调用时:

define(['underscore', 'backbone.localStorage'], function(_, Backbone) {
Run Code Online (Sandbox Code Playgroud)

至:

define(['underscore', 'backbone', 'backbone.localStorage'], function(_, Backbone) {
Run Code Online (Sandbox Code Playgroud)

为什么?

垫片exports配置被用来说'当我要求backbone.localStorage,返回我Backbone'.

这允许'backbone.localStorage'在Todo模块中简单地用作Backbone.

但现在backbone.localStorage支持AMD并显式返回define调用中的值.所以BackboneTodo.js中的值不再是Backbone库,而是实际的构造函数Backbone.LocalStorage

据我所知,shimAMD模块会忽略配置,或者至少不应该使用:

只使用其他"shim"模块作为shimmed脚本的依赖项,或者没有依赖项的AMD库,并在创建全局(如jQuery或lodash)之后调用define().否则,如果您使用AMD模块作为shim配置模块的依赖项,则在构建之后,可能不会在构建中的填充代码执行之后评估该AMD模块,并且将发生错误.最终的解决方法是升级所有已调整的代码以进行可选的AMD define()调用.

为了解决这个问题,需要在Todo.js中添加额外的依赖项,以便回调参数匹配.

希望这是有道理的.