2

What I want:

All JavaScript/TypeScript files that require jQuery to contain it, but all my async chunks that require jQuery to not contain jQuery and use the window.jQuery variable instead.

The Problem:

The thing is: there is a jQuery plugin (external code) loaded as a chunk that require jQuery in its code (UMD) so the chunk itself contains its own jQuery after Webpack build ... :(

Context:

I have a main file that imports jQuery and makes it available as a global in window because of legacy code. Then this main file will async load some chunks.

One of the chunk is an external package (so I can not change the code). It is a jQuery plugin written with UMD.

It kind of look like it:

// main.js

import $ from 'jquery';

window.$ = window.jQuery = $; // In reality with expose-loader.

import(/* webpackChunkName: jquery.plugin */ 'jquery-plugin').then(() => {
    $('element').plugin();
});

The UMD of the plugin looks like that:

// jquery-plugin.js

(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // Webpack gets here by default.
        define(['jquery'], factory);
    } else if (typeof exports === 'object' && typeof require === 'function') {
        // Webpack gets here if I disable AMD in Webpack config.
        factory(require('jquery'));
    } else {
        // I would like Webpack to get here.
        factory(jQuery); // Browser global
    }
}(function($) { /* plugin code */ })

What I tried:

I have seen webpack.ProvidePlugin but it seems to be applied to all files only, so my main.js will not contain jQuery which would be a big problem.


Ignoring jQuery in the specific library with webpack.IgnorePlugin but it results in a module not found error since the file does not contain jQuery anymore but the jQuery plugin code has not change and still requires jQuery ...

// webpack.config.js

{
    plugins: [
        new webpack.IgnorePlugin(/^jquery$/, /node_modules\/jquery-plugin/),
    ]
}

jquery.autocomplete.js:19 Uncaught (in promise) Error: Cannot find module 'jquery'


From what I have understood, I can not use externals as object because it would be external for all files. So I tried it with the function syntaxe but did not make it work. I feel like it may be the solution, but I am missing something:

// webpack.config.js

{
    externals: [
        function(context, request, callback) {
            if (/^jquery$/.test(request) && /node_modules\/jquery-plugin/.test(context)){
                return callback(null, 'amd ' + request);
            }
            callback();
        },
    ],
}

external_"jquery":1 Uncaught (in promise) ReferenceError: WEBPACK_EXTERNAL_MODULE__638 is not defined


Maybe there are some splitChunk options to deal with something like that?


IDK :'(

Help is very welcome ^^'

Thanks

Heymath

Heymath
  • 21
  • 2

0 Answers0