Exposez jQuery à un objet Window réel avec Webpack

111

Je souhaite exposer l'objet jQuery à l'objet de fenêtre global qui est accessible dans la console développeur dans le navigateur. Maintenant, dans ma configuration Webpack, j'ai les lignes suivantes:

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

Ces lignes ajoutent les définitions jQuery à chaque fichier dans mes modules webpack. Mais lorsque je construis le projet et que j'essaye d'accéder à jQuery dans la console du développeur comme ceci:

window.$;
window.jQuery;

il dit que ces propriétés ne sont pas définies ...

Y'a t'il un moyen d'arranger cela?

ferbolg
la source
1
Puis-je définir this: 'window'aussi? Étant donné que de nombreuses bibliothèques supposent que la thisvariable est l'objet Window
Abhinav Singi

Réponses:

129

Vous devez utiliser le chargeur d'exposition .

npm install expose-loader --save-dev

Vous pouvez soit le faire lorsque vous en avez besoin:

require("expose?$!jquery");

ou vous pouvez le faire dans votre configuration:

loaders: [
    { test: require.resolve('jquery'), loader: 'expose?jQuery!expose?$' }
]

MISE À JOUR : À partir du webpack 2, vous devez utiliser exposer-loader au lieu d' exposer :

module: {
    rules: [{
        test: require.resolve('jquery'),
        use: [{
            loader: 'expose-loader',
            options: '$'
        }]
    }]
}
Matt Derrick
la source
11
Le ProvidePlugindoit principalement utilisé dans les situations où les bibliothèques tierces dépendent de la présence d'une variable globale.
Johannes Ewald
J'ai fait l'hypothèse incorrecte que la question utilisait le plugin provide à des fins `` paresseuses '' que j'ai beaucoup vues en ligne mais vous avez raison :)
Matt Derrick
8
C'est exactement ce que je cherchais et juste pour ajouter plus, pour les chargeurs, vous pouvez aussi le faire en une seule ligne:{test: /jquery\.js$/, loader: 'expose?jQuery!expose?$'}
Fernando
8
Ne pouvez-vous pas simplement ajouter un premier script qui le fait $ = require('jquery'); window.jQuery = $; window.$ = $;? (pas besoin expose-loader)
herman
1
Selon la page par GitHub exposer tractopelles la syntaxe webpack 2 est la suivante: module: { rules: [{ test: require.resolve('jquery'), use: [{ loader: 'expose-loader', options: 'jQuery' },{ loader: 'expose-loader', options: '$' }] }] }. C'est le seul moyen pour que jQuery soit exposé et il utilise la nouvelle syntaxe module.rules .
Gavin Sutherland
84

FournirPlugin remplace un symbole dans une autre source via l'importation respective, mais n'expose pas le symbole sur l'espace de noms global. Un exemple classique sont les plugins jQuery. La plupart d'entre eux s'attendent simplement jQueryà être définis globalement. Avec le, ProvidePluginvous vous assurez que jQuery est une dépendance (par exemple chargée avant) et que l'occurrence de jQuerydans leur code serait remplacée par l'équivalent brut de webpack require('jquery').

Si vous avez des scripts externes reposant sur le symbole pour être dans l'espace de noms global (comme disons un JS hébergé en externe, des appels Javascript dans Selenium ou simplement en accédant au symbole dans la console du navigateur), vous souhaitez utiliser à la expose-loaderplace.

En bref: FournirPlugin gère les dépendances au moment de la construction pour les symboles globaux tandis que le expose-loadergère les dépendances d'exécution avec les symboles globaux.

Joscha
la source
2
Merci pour l'explication
Foton
Exemple de providePlugin avec webpack de la documentation officielle: webpack.js.org/plugins/provide-plugin/#usage-jquery
James Gentes
33

On dirait que l' windowobjet est exposé dans tous les modules.

Pourquoi ne pas simplement importer / exiger JQueryet mettre:

window.$ = window.JQuery = JQuery;

Vous devrez vous assurer que cela se produit avant d'exiger / d'importer tout module qui l'utilise window.JQuery, soit dans un module requérant, soit dans le module où il est utilisé.

mhess
la source
Solution la plus simple sans ajouter de nouvelle dépendance. Merci!
fatihpense
Cela ne fonctionnera pas si d'autres modules imbriqués utilisent la variable, simplement `` non définie ''
aboutqx
4
Eh bien, cela fonctionne lors de l'utilisation requirealors que nonimport
aboutqx
@aboutqx Je ne sais pas ce que vous voulez dire. Ma réponse supposait que JQuery avait déjà été importé / requis et assigné à une variable nommée JQuery.
mhess le
2
@mhess lorsque vous utilisez import, vous pouvez obtenir une erreur, car imports sont triés en haut du fichier et requirerestent là où ils ont été placés. Ainsi, l'ordre d'exécution ne change que importlorsque la variable de fenêtre n'est pas définie.
aboutqx
16

Cela a toujours fonctionné pour moi. y compris pour webpack 3 window.$ = window.jQuery = require("jquery");

SharpCoder
la source
2
meilleure solution ! 2018
waza123
6

Aucun de ces éléments n'a fonctionné pour moi. (et je n'aime vraiment pas la syntaxe exposer-loader). Au lieu,

J'ai ajouté à webpack.config.js:

var webpack = require('webpack');
module.exports = {
   plugins: [
       new webpack.ProvidePlugin({
           $: 'jquery',
       })     
   ]
}

Que tous les modules ont accès via jQuery via $.

Vous pouvez l'exposer à la fenêtre en ajoutant ce qui suit à l'un de vos modules fournis par webpack:

window.$ = window.jQuery = $
Antoine Vo
la source
1
Cela a fonctionné pour moi en utilisant webpack-stream dans les coulisses
klewis
1

Mise à jour pour Webpack v2

Installez exposer-loader comme décrit par Matt Derrick:

npm install expose-loader --save-dev

Insérez ensuite l'extrait de code suivant dans votre webpack.config.js:

module.exports = {
    entry: {
        // ...
    },
    output: {
        // ...
    },
    module: {
        loaders: [
                { test: require.resolve("jquery"), loader: "expose-loader?$!expose-loader?jQuery" }
        ]
    }
};

(à partir de la documentation expose-loader )

Cologne_Muc
la source
Je ne peux plus faire fonctionner cela dans aucune version de Webpack. Je ne sais pas ce qui a changé, mais la seule façon de faire reconnaître jQuery ou $ est de le fairewindow.jQuery = require('jquery');
trpt4him
0

Dans mon cas fonctionne

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