Search code examples
webpackbreezewebpack-4webpack-provide-plugin

webpack ProvidePlugin doesn't work for breeze


I am trying to use breeze with a TypeScript web application that uses webpack (4.20.2). These entries are in my npm package.json file:

"dependencies": {
    "bootstrap": "3.3.6",
    "breeze-client": "1.7.1",
    "es6-promise-promise": "1.0.0",
    "jquery": "2.2.1"
  }

I have a vendor webpack config that has the following:

  entry: {
            vendor: [
                'bootstrap',
                'bootstrap/dist/css/bootstrap.css',
                'breeze-client',
                'es6-promise-promise',
                'jquery'
            ]
        },
   plugins: [
            new webpack.ProvidePlugin({ 
                  $: 'jquery', 
                  jQuery: 'jquery', 
                  Promise: 'es6-promise-promise', 
                  Q: "q" 
            })
        ]

I was getting

Error: Q is undefined. Are you missing Q.js? See https://github.com/kriskowal/q

So I added a polyfill to my code to use ES6 Promises for Q, and do this in my startup code:

import { config } from 'breeze-client'
import { Q } from './lib/my-q-implementation';
config.setQ(Q)

Now I get this:

Unable to locate jQuery

I'm pretty sure boostrap looks for a global jQuery, so I think the problem is breeze.

Why is breeze not seeing the global jQuery? How do I fix this?


Solution

  • Very hacky but I got it working using the imports-loader.

    module: {
     rules: [
        { 
         test: require.resolve('breeze-client/breeze.debug'), 
         use: 'imports-loader?this=>window,window.jQuery=jquery,window.ko=knockout,global=>{window: this}' 
        },
       ]
    }
    

    Which puts this at the top of the breeze script.

    var window = (window || {});
    window.jQuery = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js");
    var window = (window || {});
    window.ko = __webpack_require__(/*! knockout */ "./node_modules/knockout/build/output/knockout-latest.debug.js");
    var global = {window: this};
    

    I don't like it because it puts jquery and ko in the global scope.

    I tried this, among other things, (for jquery) and it did not work:

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

    AND with this in place, I still have to do this in another script that references "$":

    import * as $ from 'jquery';
    

    Tried this in my startup script also with no luck:

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

    Hope this helps someone and hope someone can chime in with a better solution.