11

I am trying to make a jQuery plugin accessible to inline JavaScript using Webpack 4.

I am using the PluginProvider to make jQuery available to my website:

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

This is working fine and I can access jQuery from any page that includes my bundle.

I tried to add bootstrap-datepicker by creating a bundle called vendor.js with the following contents:

import 'bootstrap-datepicker';

I can call $('input').datepicker() from within the vendor.js bundle, however if I try and call it using an inline <script> I get:

Uncaught TypeError: $(...).datepicker is not a function

How can I configure Webpack 4 to make bootstrap-datepicker available to the global scope?


UPDATE

I've uploaded the sourcecode demonstrating this issue here: https://github.com/LondonAppDev/webpack-global-jquery-issue

It appears the issue is that the second bundle import is re-adding jQuery without the datpicker add-on. Is there a way around this?

LondonAppDev
  • 8,501
  • 8
  • 60
  • 87
  • Can you create a little git repo which reproduces your problem, so I can hook into it easier – Legends Apr 13 '18 at 10:52
  • Hey @Legends, sure! I've pushed the example here: https://github.com/LondonAppDev/webpack-global-jquery-issue – LondonAppDev Apr 13 '18 at 14:06
  • Sorry, but I cannot find your vendor.js bundle in your repo. But I can see issue within your current repo, and that is that you put main.js as an entry point, which is wrong. With webpack 4, entry points are only for real entry points - no vendor scripts like in wp3 and CommonsChunkPlugin. – Legends Apr 13 '18 at 22:11
  • Just update your repo and recreate the issue as mentioned in your post. – Legends Apr 13 '18 at 22:13
  • I'm also getting this problem, where the second bundle import is re-adding jQuery without the other plugins installed to the global jQuery variable. Anyone know a solution? – Nathan Jones May 18 '18 at 23:55

1 Answers1

16

I've gone a few rounds with this type of issue and had the most success with the expose-loader. In your webpack config you should set up a section for jQuery using the following expose loader configuration:

module.exports = {
  module: {
    rules: [
      {
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: 'jQuery'
        }, {
            loader: 'expose-loader',
            options: '$'
        }]
      },
      ...
    ]
  }
}

There is a similar SO posts here:

How to import jquery in webpack (their regex pattern did not work for me)

Expose jQuery to real Window object with Webpack

Webpack 2 loading, exposing, and bundling jquery and bootstrap

You should be able to find several other articles/posts using this configuration, it is the only one that I have successfully been able to get to work to date.

Also of note, bootstrap 4 seems to also load or do a require on jQuery internally, so if you include an import or require after your jQuery import/require and plugins, it will reinit jQuery and cause your plugins to lose scope.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Russell Shingleton
  • 3,176
  • 1
  • 21
  • 29
  • 1
    This worked for me after hours of fighting... every $ was a different instance so plugins didn't add themselves to the window's $. I did also have to rmeove the jQuery/$ config from ProvidePlugin. – Whatcould Aug 15 '19 at 01:17