webpack: Can't get to require jQuery to work

I’m having problems understanding how to require a third party library with webpack and I cannot find information in docs neither in website. This is the directory structure I have:

   js/
    |- vendor/jquery/jquery.js
    |-web.js
    |-home.js

This is my webpack.config.js

{
    context : __dirname + '/js',
    entry   : "./web.js",
    output: {
        filename: "bundle.js",
        path : 'js',
        publicPath : 'js/',
        pathInfo : true
    }
}

web.js has only this require to include home.js:

require(['./home.js']);

And, inside home.js I’m trying to require jquery as a module:

define(['./vendor/jquery/jquery.js'], function($){
$(document).ready(function(){
    // Resize .home-hero height to full height of window
    sizeContent();
    $(window).resize(sizeContent);
    function sizeContent() {
        var newHeight = $(window).height();
        $(".home-hero").css("height", newHeight);
    }
});
});

When executing in browser, all I get is: Uncaught SyntaxError: Unexpected token [ 1.bundle.js:30

Here are the files generated by webpack:

I know Github/Issues is not intended to ask for support, but I guess this can be related to a lack of examples including jQuery/Backbone/Etc…

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 23 (15 by maintainers)

Commits related to this issue

Most upvoted comments

By the way there are several ways to require a third-party lib:

  • CommonJs require("./vendor/jquery/jquery.js") (sync)
  • AMD require require(["./vendor/jquery/jquery.js"], function($) { xyz }) (async)
  • AMD define define(["./vendor/jquery/jquery.js"], function($) { xyz }) (sync)

If you don’t want to provide a path: require("jquery") require(["jquery"], function($) {}) define(["jquery"], function($) {}):

  • by option: resolve: { alias: { jquery: "/path/to/jquery" } }
  • by directory: Put jquery into a folder web_modules.

If you just want to use $ and jQuery without require:

  • option: provide: { $: "/path/to/jquery", jQuery: "/path/to/jquery" }

I prefer CommonJs too, but webpack supports both. So you are free to use what you like most.

Regarding the jQuery issue:

jQuery 2.x exports itself to the window object, even if a CommonJs loader is availible.

Instead of adding window.jQuery = window.$ = require("jquery") to your entry file, you can use a loader to do this. While updating the docs I luckily found one ^^: expose-loader

define(["expose?$!expose?jQuery!jquery", "aplugin"], function($) { });

Depends on the plugin…

If the plugin expect jQuery to be a valid identifier in scope, provide will work.

But some jquery plugins expect jQuery to be on the window or this object. Than provide fails, as it only provide “free” variables.

The simple solution is to add window.jQuery = window.$ = require("jquery"); to your entry file. That should solve all problems with jquery plugins.

If you think that is bad: There are two loaders for fixing various weird modules: imports-loader and exports-loader:

So require("import?window=>{jQuery:require('jquery')}!aplugin") injects a fake window containing your jquery. jquery is not exposed on the real global object.

Or you may define window.jQuery to jQuery with {define: {"window.jQuery": "jQuery"}} (combined with the provide option)

Plugins expecting jQuery in scope can be also called without provide: require("imports?jQuery=jquery!aplugin")

To summarize:

  • provide globally free vars
  • imports-loader locally free vars
  • define globally replacement

I also had to use amd: { jQuery: true } in my webpack config…