Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backbone packaging issue #34

Closed
miffels opened this issue Nov 6, 2012 · 17 comments
Closed

Backbone packaging issue #34

miffels opened this issue Nov 6, 2012 · 17 comments

Comments

@miffels
Copy link

miffels commented Nov 6, 2012

Hi sokra,

yesterday I tried adding Backbone to one of my projects and ran into some issue I do not fully understand. My setup is webpack 0.7.8, Backbone 0.9.2 (both in web_modules and node_modules, installed locally via jam or npm respectively) and enhanced-require 0.4.0-beta3 running on node 0.8.11.

When I try to webpack a file with the following contents

'use strict';
require = require('enhanced-require')(module, {
    recursive: true
});

var Backbone = require('backbone');

console.log(Backbone);

I get the following warning-error-mix:

<WARN> Cannot find module 'exports'
 Error: Module "exports" not found in context "<project path>\web_modules\backbone"
  Error: non in any path of paths
 @ <project path>\web_modules\backbone\backbone.js (line 15, column 36) Use --force to continue. </WARN>

Since it is a mere warning, I could force the build though, giving me about what I expected in the console.log line. Nevertheless, did you ever face that warning? How can I get rid of it?

Interestingly enough, when I remove the jam version of Backbone, webpack runs without complaining about anything. Then again, there is only the Backbone namespace in the console.log output, i.e. it containts neither View, nor Model, nor any other object or function.

Best regards,
Michael

@Phoscur
Copy link

Phoscur commented Nov 6, 2012

Here are those first lines of backbone.js creating the issue:

(function(root, factory) {
  // Set up Backbone appropriately for the environment.
  if (typeof exports !== 'undefined') { // why is exports === undefined?
    // Node/CommonJS, no need for jQuery in that case.
    factory(root, exports, require('underscore'));
  } else if (typeof define === 'function' && define.amd) {
    // AMD
    define(['underscore', 'jquery', 'exports'], function(_, $, exports) { // LINE 15
      // Export global even in AMD case in case this script is loaded with
      // others that may still expect a global Backbone.
      root.Backbone = factory(root, exports, _, $);
    });
  } else {

sokra added a commit to webpack/enhanced-require that referenced this issue Nov 6, 2012
@miffels
Copy link
Author

miffels commented Nov 6, 2012

Unfortunately, I stumbled across another error while trying to ignore the above warning: When I define my own View via Backbone.View.extend():

Uncaught TypeError: undefined is not a function main.js:2654
_.extend.make main.js:2654
_.extend._ensureElement main.js:2731
Backbone.View main.js:2606
child main.js:2852
(anonymous function) main.js:1456
require main.js:12
amdRequire main.js:70
(anonymous function) main.js:34
(anonymous function) main.js:35
require main.js:12
c main.js:21
(anonymous function) main.js:23

For now, I worked around the issue by including jQuery, underscore and Backbone manually inside the <head> tag of my index.html page. For this to work I need to tell jshint that these are globals, but except that, it works. This is just a very unclean solution given that webpack should be able to add them to the bundle when these are required.

@sokra sokra closed this as completed in 80989e7 Nov 6, 2012
@sokra sokra reopened this Nov 6, 2012
@Phoscur
Copy link

Phoscur commented Nov 6, 2012

Maybe there is a way to omit the AMD flags completely if you wrap the define function and export AMD modules automatically?

@sokra
Copy link
Member

sokra commented Nov 6, 2012

I fixed the exports bug.

Keep in mind that the versions published to the jam package manager are special AMD versions and maybe behave different from the original versions.

It also includes the jam jquery, which requires a special jquery flag in the require.amd object. You need to set it via webpacks options: { amd: { jQuery: true }}.

In CommonJS Backbone don't require jquery, thats weird...

  if (typeof exports !== 'undefined') {
    // Node/CommonJS, no need for jQuery in that case.
    factory(root, exports, require('underscore'));
  }

@sokra
Copy link
Member

sokra commented Nov 6, 2012

Maybe Backbone.setDomLibrary(require("jquery")) helps...

@miffels
Copy link
Author

miffels commented Nov 8, 2012

I assume this issue can be closed. I switched from grunt.js to a custom build.js file for building the project with webpack and got it all working. As far as I'm aware Phoscur has no issues anymore either.

Edit: Actually, Backbone.setDomLibrary(require("jquery")) seems to be necessary. I did not try if a single call suffices, though.

@miffels miffels closed this as completed Nov 8, 2012
@miffels
Copy link
Author

miffels commented Jan 30, 2013

Hi sokra,

I could go nuts: Just tried Backbone 0.9.10 and it seems that setDomLibrary() got removed. Any ideas?

I checked all, the "vanilla" version, the jam and the npm module. I am not sure if it is save to remove that call. Currently I get the following errors, not sure if that's the actual cause though:

Uncaught TypeError: Expecting a function in instanceof check, but got [object Object] app.js:1694
_.extend.setElement app.js:1694
_.extend._ensureElement app.js:1762
Backbone.View app.js:1648
child app.js:1880
child app.js:1880
Application.start app.js:3424
...

which is, more specifically, the following method from Backbone.View:

setElement: function(element, delegate) {
      if (this.$el) this.undelegateEvents();
      this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
Uncaught TypeError: Expecting a function in instanceof check, but got [object Object]
      this.el = this.$el[0];
      if (delegate !== false) this.delegateEvents();
      return this;
    }

I do not think there is a way to fix this, so I just wanted to let you know. I even tried the version that used to work earlier (0.9.2) - just to discover that this one has been changed as well! Gah! What is this?

Cheers,
Michael

@miffels
Copy link
Author

miffels commented Jan 30, 2013

Hi sokra,

quick update: I managed to restore an "old" old version of Backbone, which still works. But this is definitely a 0.9.2 version which is totally different from the 0.9.2 currently on jam and npm.

Cheers,
Michael

@sokra
Copy link
Member

sokra commented Jan 30, 2013

Hi,

I think you can just replace the setDomLibrary call with a simple assignment to $.

Backbone.setDomLibrary(require("jquery"));
// =>
Backbone.$ = require("jquery");

@miffels
Copy link
Author

miffels commented Feb 6, 2013

Hi sokra,

Sorry for the late confirmation - I tried that once, it didn't work. Then I investigated Backbone, realizing that it should work, though. When I gave it a second shot a couple of minutes ago, this resolved my issue. Thanks!

Cheers,
Michael

@pherrymason
Copy link

Where should Backbone.$ = require("jquery"); be placed? In the backbone.js file?

@jhnns
Copy link
Member

jhnns commented Oct 15, 2013

You should not modify your dependencies because thus you can't just update them. I'm placing this kind of initialization code in my entry file. The entry file is the file you give to webpack.

@pherrymason
Copy link

Yes, I was asking because I didn't feel comfortable modificating an
external library

On Tue, Oct 15, 2013 at 9:35 AM, Johannes Ewald notifications@github.comwrote:

You should not modify your dependencies because thus you can't just update
them. I'm placing this kind of initialization code in my entry file.
The entry file is the file you give to webpack.


Reply to this email directly or view it on GitHubhttps://github.com//issues/34#issuecomment-26314441
.

@vladikoff
Copy link

@sokra @jhnns Is there a better way to shim 'jquery' into 'Backbone' now?

With Require.js I use:

  shim: {
    underscore: {
      exports: '_'
    },
    backbone: {
      deps: [
        'underscore',
        'jquery'
      ],
      exports: 'Backbone'
    },

With WebPack I get "$: undefined" and it is causing a bit of trouble
image

@akre54
Copy link
Contributor

akre54 commented Jul 31, 2014

Backbone.$ is undefined if you're using CommonJS (I work on Backbone). You must set it yourself, preferably in your app initialization code before any Backbone.$ functions are used.

@vladikoff
Copy link

@akre54 hm I'll try to force AMD loading then

@Georgegriff
Copy link

Has anyone got any clarifaction on how to fix this issue? Im migrating from RequireJS with Backbone 1.1.0 and i've encountered this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants