Managing jQuery plugin dependency in webpack

前端 未结 11 1220
陌清茗
陌清茗 2020-11-22 01:17

I\'m using Webpack in my application, in which I create two entry points - bundle.js for all my JavaScript files/codes, and vendors.js for all libraries like jQuery and Reac

相关标签:
11条回答
  • 2020-11-22 01:34

    I don't know if I understand very well what you are trying to do, but I had to use jQuery plugins that required jQuery to be in the global context (window) and I put the following in my entry.js:

    var $ = require('jquery');
    window.jQuery = $;
    window.$ = $;
    

    The I just have to require wherever i want the jqueryplugin.min.js and window.$ is extended with the plugin as expected.

    0 讨论(0)
  • 2020-11-22 01:34

    The best solution I've found was:

    https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059

    Basically, you need to include a dummy variable on typings.d.ts, remove any "import * as $ from 'jquery" from your code, and then manually add a tag to jQuery script to your SPA html. This way, webpack won't be in your way, and you should be able to access the same global jQuery variable in all your scripts.

    0 讨论(0)
  • 2020-11-22 01:39

    For global access to jquery then several options exist. In my most recent webpack project, I wanted global access to jquery so I added the following to my plugins declarations:

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

    This then means that jquery is accessible from within the JavaScript source code via global references $ and jQuery.

    Of course, you need to have also installed jquery via npm:

    $ npm i jquery --save
    

    For a working example of this approach please feel free to fork my app on github

    0 讨论(0)
  • 2020-11-22 01:41

    This works in webpack 3:

    in the webpack.config.babel.js file:

    resolve: {
        alias: {
             jquery: "jquery/src/jquery"
        },
     ....
    }
    

    And use ProvidePlugin

    new webpack.ProvidePlugin({
            '$': 'jquery',
            'jQuery': 'jquery',
        })
    
    0 讨论(0)
  • 2020-11-22 01:46

    You've mixed different approaches how to include legacy vendor modules. This is how I'd tackle it:

    1. Prefer unminified CommonJS/AMD over dist

    Most modules link the dist version in the main field of their package.json. While this is useful for most developers, for webpack it is better to alias the src version because this way webpack is able to optimize dependencies better (e.g. when using the DedupePlugin).

    // webpack.config.js
    
    module.exports = {
        ...
        resolve: {
            alias: {
                jquery: "jquery/src/jquery"
            }
        }
    };
    

    However, in most cases the dist version works just fine as well.


    2. Use the ProvidePlugin to inject implicit globals

    Most legacy modules rely on the presence of specific globals, like jQuery plugins do on $ or jQuery. In this scenario you can configure webpack, to prepend var $ = require("jquery") everytime it encounters the global $ identifier.

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

    3. Use the imports-loader to configure this

    Some legacy modules rely on this being the window object. This becomes a problem when the module is executed in a CommonJS context where this equals module.exports. In this case you can override this with the imports-loader.

    Run npm i imports-loader --save-dev and then

    module: {
        loaders: [
            {
                test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
                loader: "imports-loader?this=>window"
            }
        ]
    }
    

    The imports-loader can also be used to manually inject variables of all kinds. But most of the time the ProvidePlugin is more useful when it comes to implicit globals.


    4. Use the imports-loader to disable AMD

    There are modules that support different module styles, like AMD, CommonJS and legacy. However, most of the time they first check for define and then use some quirky code to export properties. In these cases, it could help to force the CommonJS path by setting define = false.

    module: {
        loaders: [
            {
                test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
                loader: "imports-loader?define=>false"
            }
        ]
    }
    

    5. Use the script-loader to globally import scripts

    If you don't care about global variables and just want legacy scripts to work, you can also use the script-loader. It executes the module in a global context, just as if you had included them via the <script> tag.


    6. Use noParse to include large dists

    When there is no AMD/CommonJS version of the module and you want to include the dist, you can flag this module as noParse. Then webpack will just include the module without parsing it, which can be used to improve the build time. This means that any feature requiring the AST, like the ProvidePlugin, will not work.

    module: {
        noParse: [
            /[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/
        ]
    }
    
    0 讨论(0)
提交回复
热议问题