0

I have a problem loading jquery-ui in a project that's built with browserify via gulp. In my code, I have:

import $ from "jquery";
import "jquery-ui";

The error is Uncaught ReferenceError: jQuery is not defined. Looking at the jquery-ui code at the point the error occurs, I see:

( function( factory ) {
  if ( typeof define === "function" && define.amd ) {
    // AMD. Register as an anonymous module.
    define( [ "jquery", "./version" ], factory );
  } else {
  // Browser globals
    factory( jQuery );   // <<--- error raised here
  }
}( function( $ ) {
...

The core issue is that, while the import of jquery has defined $, it has not set the global jQuery variable.

I've seen a lot of solutions to similar issues involving creating a shim for loading jQuery, but this problem seems different. It's not that jQuery is not being loaded (otherwise $ would also be undefined), it's that jquery-ui is expecting jQuery as a global alias.

I've also seen a lot of suggestions to manually set window.jQuery = $, or similar. This also doesn't work in my case, because the bundle of code that is being run is created by browserify, so I don't get to control the order in which modules are being created, so it's unclear to me where in my code I would put such a statement.

For reference, my gulp task is:

browserify(
  "./app/es/app.es",
  {
    debug: true,
  }
)
.transform(babel)
.on("error", function(err) { gutil.log(err); this.emit("end"); })
.pipe(source("build.js"))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write("./"))
.pipe(gulp.dest("./build/js"));

I have tried inserted a browserify-shim transform with the following config:

"browserify-shim": {
  "jquery": "jQuery"
},

but it didn't change the observed behaviour.

1 Answer 1

4

The problem is that after transformation by babel, the statement import rises to the top:

import $ from 'jquery';
window.jQuery = window.$ = require('jquery');
import 'jquery-ui';

=>

'use strict';

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

require('jquery-ui');

function _interopRequireDefault(obj) { 
    return obj && obj.__esModule ? obj : { default: obj }; 
}

window.jQuery = window.$ = require('jquery');

Possible solutions:

1) Use require instead import:

window.jQuery = window.$ = require('jquery');
require('jquery-ui');

2) Use the additional wrapper over jquery:

_jquery.js:

import $ from 'jquery';
window.jQuery = window.$ = $;

export default $;

app.es:

import "./_jquery.js";
import "jquery-ui";
Sign up to request clarification or add additional context in comments.

1 Comment

I appreciate the explanation of what the Babel transform is doing with the import statements, so thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.