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

The way to shim modules relying on `window`, `window.jQuery` and `document` #542

Closed
utensil opened this issue Oct 19, 2014 · 5 comments

Comments

Projects
None yet
3 participants
@utensil
Copy link

commented Oct 19, 2014

I was migrating a site to webpack and encountered a problem similar to the one discussed here at https://gitter.im/webpack/webpack/archives/2014/07/23 by @mathieumg , which was a dependency on window.jQuery.

My problem was that one of my dependencies (to be specific: https://github.com/eternicode/bootstrap-datepicker ) depended on window, window.jQuery and document.defaultView.

After a lot of trial and error, eventually I figured out a way combining externals , imports-loader and ProvidePlugin:

In webpack.config.js:

// Only the relevant part
{
    output: {
        libraryTarget: "var"
    },
    externals: [
        {
            "window": "window"
        }
    ],
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        })
    ]  
}

In my entry js:

    var window = require("window");
    window.jQuery = jQuery;

    require("imports?this=>window!bootstrap-datepicker");
    require("imports?this=>window!bootstrap-datepicker.zh-CN");

Here I share my discovery and wonder whether there're other approaches and whether this is the best practice of shimming such kind of libraries.

@sokra

This comment has been minimized.

Copy link
Member

commented Oct 19, 2014

    externals: [
        {
            "window": "window"
        }
    ],

has no effect unless you require("window").


You could try this with the newest webpack version:

        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
            "window.jQuery": "jquery"
        })
@utensil

This comment has been minimized.

Copy link
Author

commented Oct 20, 2014

sokra commented 5 hours ago
has no effect unless you require("window").

Yes, that's why I needed to do so in my app entry js.

You could try "window.jQuery": "jquery"

Unfortunately, although this works for window.jQuery, but it can't provide document to the "script-style lib"(i.e. written to be directly included as a script tag and relies on global variables), so it fails with the dependency on document.defaultView.

And in webpack, there seems to be no other way to provide the browser's document to a "script-style lib", except:

  • use "externals" in config and "require" in entry to get the global from browser
  • inject the globals by imports?this=THE_GLOBAL_RQUIRED_AS_LOCAL

And in my case, this is externals: [{"window": "window"}], var window = require("window") and imports?this=window.

@sokra

This comment has been minimized.

Copy link
Member

commented Oct 23, 2014

imports?this=>window don't require a window module.

@utensil

This comment has been minimized.

Copy link
Author

commented Oct 24, 2014

But I've required window as a local variable, so it can be imported.

UPDATE: The line above is a misunderstanding of my code(which works). What actually happened is that I injected jQuery into the global window by requiring module window(which in turn was just exporting the global window), and then using imports-loader with the => syntax, injected the global window into the target module.

In my case, because window is also a module, using imports-loader with the = syntax would also work, just by automatically requiring the module window.

@shama

This comment has been minimized.

Copy link
Member

commented Jul 19, 2015

Closing as this issue appears to be resolved. Please reopen if it has not. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.