Webpack: how to make angular auto-detect jQuery and use it as angular.element instead of jqLite?

前端 未结 5 1105
甜味超标
甜味超标 2021-01-31 14:42

I\'m using Webpack to build an Angular 1.4 project. The project makes use of several jQuery plugins, which are wrapped into angular directives. Those directives internally use <

5条回答
  •  暗喜
    暗喜 (楼主)
    2021-01-31 15:35

    So, I give my solution, which is actually a mashup of the @BobSponge answer and @Bob's hints / comments. So nothing original, just showing what works for me (in a project not using Babel / ES6, BTW) and attempting to explain why it works...

    The (final) trick is indeed to use the expose loader.

    As explained in their page, we have to put in module.loaders:

    { test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" },
    

    Moreover, in the plugins list, I have:

            new webpack.ProvidePlugin(
            {
                $: 'jquery',
                jQuery: 'jquery',
                _: 'lodash',
                // [...] some other libraries that put themselves in the global scope.
                //angular: 'angular', // No, I prefer to require it everywhere explicitly.
            }),
    

    which actually finds the global occurrences of these variables in the code, and require them into variables local to each module. It eases the migration of an existing project (from RequireJS to Webpack) as I do... I think we can do without this plugin if you prefer to be explicit in your imports.

    And, importantly (I think), in the entry point of the application, I require them in the order I want them. In my case, I made a vendor bundle, so that's the order in this bundle.

    require('jquery');
    
    require('lodash');
    // [...]
    
    var angular = require('angular');
    // Use the angular variable to declare the app module, etc.
    

    Webpack will add the libraries to the relevant bundle in the order it sees the requires (unless you use a plugin / loader that reorder them). But the imports are isolated (no global leak), so Angular wasn't able to see the jQuery library. Hence the need for expose. (I tried window.jQuery = require('jquery'); instead, but it didn't work, perhaps it is too late.)

提交回复
热议问题