nytimes / backbone.stickit

Backbone data binding, model binding plugin. The real logic-less templates.
MIT License
1.64k stars 176 forks source link

How to include Stickit with Browserify #214

Closed mulderp closed 10 years ago

mulderp commented 10 years ago

Hi,

I am trying to include Stickit with Browserify as follows:

var Backbone = require("backbone");
Backbone.Stickit = require("backbone.stickit");
console.log(Backbone);

var newAddress = Backbone.View.extend({
  // ....
});

But the Stickit methods are not added to the view/Backbone.

Any ideas what to do?

Thanks!

akre54 commented 10 years ago

Try it without assigning to Backbone.Stickit. The plugin will set up the namespace itself, and it doesn't return anything from the module loader: https://github.com/NYTimes/backbone.stickit/blob/0.7.0/backbone.stickit.js#L20

mulderp commented 10 years ago

It gives a {} for that case. I also tried to bundle stickit solo, this gives also {}

The repo is: https://github.com/mulderp/firebase-addresses

mulderp commented 10 years ago

Just for reference, the two Browserify commands I use are:

browserify -r backbone.stickit:stickit > static/stickit.js

and browserify -r ./app/main.js:app > static/bundle.js

akre54 commented 10 years ago

Hrrm I have no clue. I use browserify programmatically, not sure if its a command line thing.

Make sure the body of stickit is getting reached and that the Backbone object is set properly?

mulderp commented 10 years ago

too late for today to figure out what's wrong, but probably indeed some settings from Browserify (maybe -x, -i flags ) - I will need to comeback another time.

mulderp commented 10 years ago

ping @substack - any idea how to Browserify a Backbone plugin ?

svnlto commented 10 years ago

@mulderp use this https://github.com/thlorenz/browserify-shim

ghost commented 10 years ago

The same thing happens in browserify as in node:

$ node -pe "require('backbone.stickit')"
{}

The problem is that this module hosts itself on the backbone reference for you, which is super surprising behavior for a commonjs module:

  Backbone.Stickit = {

This doesn't work because backbone is a dependency of backbone.stickit, so this code is dependent on the deduping behavior of npm, which only fires if you install backbone in a particular way and the versions exactly match. A much better API would just be to expose the stickit reference with module.exports so that these version inconsistencies aren't a problem.

Another problem is that underscore is a dependency but isn't listed in the package.json dependencies field:

$ node -e "require('backbone.stickit')"

module.js:340
    throw err;
          ^
Error: Cannot find module 'underscore'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Backbone.Stickit._handlers (/tmp/node_modules/backbone.stickit/backbone.stickit.js:9:13)
    at Object.<anonymous> (/tmp/node_modules/backbone.stickit/backbone.stickit.js:15:2)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
svnlto commented 10 years ago

here's what your browserify-shim config should look like:

shim: {
underscore: {
  path: 'node_modules/lodash/dist/lodash.underscore.js',
   exports: '_'
},
backbone: {
  path: 'node_modules/backbone/backbone.js',
  exports: 'Backbone',
  depends: {
    underscore: 'underscore'
  }
},
'stickit': {
  path: 'node_modules/...',
  exports: 'Backbone.Stickit',
  depends: {
    backbone: 'Backbone'
  }
 }
}

this enables you to require backbone.stickit like require('stickit')

ghost commented 10 years ago

You can fix this with browserify-shim, but it would be much better long-term to fix this module to not depend on backbone directly for mutation purposes, which is very fragile and not likely to work in most circumstances.

akre54 commented 10 years ago

How about we change Stickit to have Backbone as a peerDependency? I think we solved this in our project by resolving the Backbone require to our version with debowerify...

akre54 commented 10 years ago

Give master a try.

mulderp commented 10 years ago

As far as I can see, it is not resolving the deps out-of-the box. I just had a quick look at what @substack mentions, e.g. via this syntax https://github.com/powmedia/backbone.xview/blob/master/xview.js#L356-L360 . I'll play with this on a fork, and see if it would work.

mulderp commented 10 years ago

Yes, to confirm, adding that exports to the module makes it work with Browserify.

akre54 commented 10 years ago

Stickit's backbone dependency points to a different backbone module than your project's if you're on version 1.x of Backbone (stickit's dep was 0.9.. It worked for me because we were using bower / debowerify), which is ultimately the issue. Sure Stickit should export the Stickit object for you to set yourself, but it still needs to shim Backbone.View, which requires them both pointing to the same resource.

mulderp commented 10 years ago

thanks! i got it working!

mulderp commented 10 years ago

small update, I wrote a small overview on using Backbone.Stickit with browserify here: http://thinkingonthinking.com/two-way-databinding-with-stickit/