Search code examples
javascriptjquerywebpackes6-module-loader

Importing jQuery plugins in webpack


I have searched and found many articles most talking about angular or react. My project includes neither of these.

I am simply trying to import an old jquery module into a js file using webpack.

I have jquery included using this method:

plugins: [
    new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery"
    })
]

This works. I can access jquery in the files I need to.

However when I try and import a script for example:

import coverflow from '../vendor/coverflow/dist/coverflow';

source: https://github.com/coverflowjs/coverflow

I get a browser error

Cannot read property 'createElement' of undefined

When I look this up I see that 'undefined' is referring to document. How is document not defined? Why does this import not work.

using the method:

rules: [
    {
        test: require.resolve('./js/vendor/coverflow/dist/coverflow.js'),
        use: "imports-loader?this=>window"
    }
],

I get this error:

[0] Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
[0]  - configuration has an unknown property 'rules'. These properties are valid:
[0]    object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry, externals?, loader?, module?, name?, node
?, output?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?,
 target?, watch?, watchOptions? }
[0]    For typos: please correct them.
[0]    For loader options: webpack 2 no longer allows custom properties in configuration.
[0]      Loaders should be updated to allow passing options via loader options in module.rules.
[0]      Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
[0]      plugins: [
[0]        new webpack.LoaderOptionsPlugin({
[0]          // test: /\.xxx$/, // may apply this only for some modules
[0]          options: {
[0]            rules: ...
[0]          }
[0]        })
[0]      ]


Solution

  • It's likely the library you are using expects this to be set to window, but it's not. I had this same problem with modernizr and solved it with the imports-loader like this:

    module: {
      rules: [
      {
        test: require.resolve('modernizr'),
        use: [
          'expose-loader?Modernizr',
          'imports-loader?this=>window!exports-loader?window.Modernizr'
        ]
      }
    }
    

    The important part being the this=>window. You can read more details about how I solved it here.