backbone.localStorage, require.js, “Uncaught TypeError: undefined is not a function”

邮差的信 提交于 2019-12-19 10:32:31

问题


I'm following Uzi Kilon's BackboneJS / RequireJS / backbone.LocalStorage example at http://kilon.org/blog/2012/08/build-backbone-apps-using-requirejs/.

When I git clone https://github.com/uzikilon/Todos it works just fine - but it uses older versions of backbone.localstorage. If I replace lib/backbone.localStorage with the newer version http://cdnjs.cloudflare.com/ajax/libs/backbone-localstorage.js/1.1.0/backbone.localStorage-min, though, then I get "Uncaught TypeError: undefined is not a function" here: https://github.com/uzikilon/Todos/blob/master/js/models/Todo.js#L3 - why? I think this has something to do with the tricky details at http://requirejs.org/docs/api.html#config-shim or perhaps this: 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'
    }
  }
});

回答1:


The problem lies with the fact that the latest Backbone localStorage is AMD compatible, where as the version in that example is not, hence the shim config.

The fix

Remove the shim config for backbone.localStorage, you won't be needing it:

'backbone.localStorage': {
  deps: ['backbone'],
  exports: 'Backbone'
}

Then, in Todo.js change the define call from:

define(['underscore', 'backbone.localStorage'], function(_, Backbone) {

to:

define(['underscore', 'backbone', 'backbone.localStorage'], function(_, Backbone) {

Why?

The shim exports config was being used to say 'When I ask for backbone.localStorage, return me Backbone'.

This allowed 'backbone.localStorage' to be used simply as Backbone inside the Todo module.

But now backbone.localStorage supports AMD and explicitly returns a value from the define call. So the value of Backbone in Todo.js is no longer the Backbone library, but is actually a constructor for Backbone.LocalStorage

As far as I understand, the shim config is ignored for AMD modules, or at least should not be used:

Only use other "shim" modules as dependencies for shimmed scripts, or AMD libraries that have no dependencies and call define() after they also create a global (like jQuery or lodash). Otherwise, if you use an AMD module as a dependency for a shim config module, after a build, that AMD module may not be evaluated until after the shimmed code in the build executes, and an error will occur. The ultimate fix is to upgrade all the shimmed code to have optional AMD define() calls.

To fix things up the additional dependency needs to be added in Todo.js so that so that the callback parameters match up.

Hopefully that makes sense.



来源:https://stackoverflow.com/questions/18034235/backbone-localstorage-require-js-uncaught-typeerror-undefined-is-not-a-funct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!