Gestion de la dépendance du plugin jQuery dans webpack
J'utilise Webpack dans mon application, dans laquelle je crée deux points d'entrée - bundle.js pour tous mes fichiers JavaScript/les codes et les fournisseurs.js pour toutes les bibliothèques comme jQuery et React. Que dois-je faire pour utiliser des plugins qui ont jQuery comme dépendances et je veux les avoir aussi dans les vendeurs.js? Et si ces plugins avaient plusieurs dépendances?
actuellement je suis en train d'essayer d'utiliser ce plugin jQuery ici - https://github.com/mbklein/jquery-elastic . La documentation de Webpack mentionne providePlugin et import-loader. J'ai utilisé providePlugin, mais l'objet jQuery n'est toujours pas disponible. Voici comment mon webpack.config.js ressemble à -
var webpack = require('webpack');
var bower_dir = __dirname + '/bower_components';
var node_dir = __dirname + '/node_modules';
var lib_dir = __dirname + '/public/js/libs';
var config = {
addVendor: function (name, path) {
this.resolve.alias[name] = path;
this.module.noParse.push(new RegExp(path));
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jquery: "jQuery",
"window.jQuery": "jquery"
}),
new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js', Infinity)
],
entry: {
app: ['./public/js/main.js'],
vendors: ['react','jquery']
},
resolve: {
alias: {
'jquery': node_dir + '/jquery/dist/jquery.js',
'jquery.elastic': lib_dir + '/jquery.elastic.source.js'
}
},
output: {
path: './public/js',
filename: 'bundle.js'
},
module: {
loaders: [
{ test: /.js$/, loader: 'jsx-loader' },
{ test: /.jquery.elastic.js$/, loader: 'imports-loader' }
]
}
};
config.addVendor('react', bower_dir + '/react/react.min.js');
config.addVendor('jquery', node_dir + '/jquery/dist/jquery.js');
config.addVendor('jquery.elastic', lib_dir +'/jquery.elastic.source.js');
module.exports = config;
mais malgré cela, il envoie toujours une erreur dans la console du navigateur:
Uncaught ReferenceError: jQuery n'est pas défini
de même, quand j'utilise le import-loader, il jette une erreur,
besoin n'est pas défini " les
dans cette ligne:
var jQuery = require("jquery")
cependant, je pourrais utiliser le même plugin quand je ne l'ajoute pas à mes vendeurs.le fichier js et à la place l'a exigé dans la manière AMD normale comme la façon dont j'inclus mes autres fichiers de code JavaScript, comme -
define(
[
'jquery',
'react',
'../../common-functions',
'../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
$("#myInput").elastic() //It works
});
Mais ce n'est pas ce que je veux faire, car cela signifie que jquery.élastique.source.js est livré avec mon code JavaScript en paquet.js, et je veux que tous mes plugins jQuery soient dans les vendeurs.js bundle. Comment dois-je m'y prendre pour y parvenir?
11 réponses
vous avez mélangé différentes approches comment inclure les modules fournisseurs traditionnels. C'est ainsi que je m'y attaquerais:
1. Prefer unminified CommonJS / AMD over dist
la plupart des modules lient la version dist
dans le champ main
de leur package.json
. Bien que cela soit utile pour la plupart des développeurs, pour webpack il est préférable d'alias la version src
parce que de cette façon webpack est capable d'optimiser les dépendances mieux (par exemple quand en utilisant le DedupePlugin
).
// webpack.config.js
module.exports = {
...
resolve: {
alias: {
jquery: "jquery/src/jquery"
}
}
};
cependant, dans la plupart des cas, la version dist
fonctionne tout aussi bien.
2. Utiliser le ProvidePlugin
pour injecter des globals implicites
la plupart des anciens modules s'appuient sur la présence de globals spécifiques, comme le font les plugins jQuery sur $
ou jQuery
. Dans ce scénario, vous pouvez configurer webpack, à ajouter var $ = require("jquery")
chaque fois qu'il rencontre l'identifiant mondial $
.
var webpack = require("webpack");
...
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
3. Utiliser le import-loader pour configurer this
certains modules hérités s'appuient sur le fait que this
est l'objet window
. Cela devient un problème lorsque le module est exécuté dans un contexte CommonJS où this
égale module.exports
. Dans ce cas, vous pouvez outrepasser this
avec le import-loader .
Exécuter npm i imports-loader --save-dev
puis
module: {
loaders: [
{
test: /[\/\]node_modules[\/\]some-module[\/\]index\.js$/,
loader: "imports-loader?this=>window"
}
]
}
le chargeur imports peut également être utilisé pour injecter manuellement des variables de toutes sortes. Mais la plupart du temps le ProvidePlugin
est plus utile quand il s'agit de l'implicite globals.
4. Utiliser le importations-loader pour désactiver AMD
il y a des modules qui prennent en charge différents styles de modules, comme AMD, CommonJS et legacy. Cependant, la plupart du temps ils vérifient d'abord pour define
et ensuite utiliser certains excentrique code pour exporter des propriétés. Dans ces cas, il pourrait être utile de forcer la voie commune en mettant define = false
.
module: {
loaders: [
{
test: /[\/\]node_modules[\/\]some-module[\/\]index\.js$/,
loader: "imports-loader?define=>false"
}
]
}
5. Utiliser le script-loader pour importer globalement des scripts
Si vous ne vous souciez pas des variables globales et juste pour que les scripts hérités fonctionnent, vous pouvez aussi utiliser le script-loader. Il exécute le module dans un contexte global, comme si vous les aviez inclus via la balise <script>
.
6. Utilisez noParse
pour inclure les grands dists
Lorsqu'il n'y a pas de version AMD/CommonJS du module et que vous voulez inclure le dist
, vous pouvez marquer ce module comme noParse
. Alors webpack va juste inclure le module sans parsing elle, qui peut être utilisé pour améliorer les temps de construction. Cela signifie que toute caractéristique nécessitant le AST , comme le ProvidePlugin
, ne fonctionnera pas.
module: {
noParse: [
/[\/\]node_modules[\/\]angular[\/\]angular\.js$/
]
}
pour l'accès global à jquery alors plusieurs options existent. Dans mon dernier projet webpack, je voulais un accès global à jquery et j'ai donc ajouté ce qui suit à mes déclarations de plugins:
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
cela signifie donc que jquery est accessible depuis le code source JavaScript via les références globales $ et jQuery.
bien sûr, vous devez aussi avoir installé jquery via npm:
$ npm i jquery --save
pour une exemple de cette approche s'il vous plaît n'hésitez pas à bifurquer mon application sur github
Je ne sais pas si je comprends très bien ce que vous essayez de faire, mais j'ai dû utiliser des plugins jQuery qui nécessitaient que jQuery soit dans le contexte global (fenêtre) et j'ai mis ce qui suit dans mon entry.js
:
var $ = require('jquery');
window.jQuery = $;
window.$ = $;
j'ai juste besoin là où je veux jqueryplugin.min.js
et window.$
est étendu avec le plugin comme prévu.
ajoutez ceci à votre tableau de plugins dans webpack.config.js
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
'window.$': 'jquery',
})
alors exiger jQuery normalement
require('jquery');
si la douleur persiste obtenir d'Autres scripts pour le voir, essayer de le placer explicitement dans le contexte global via (dans l'entrée js)
window.$ = jQuery;
j'ai obtenu que les choses fonctionnent bien tout en exposant $
et jQuery
comme variables globales avec Webpack 3.8.1 et ce qui suit.
installer jQuery comme une dépendance de projet. Vous pouvez omettre @3.2.1
pour installer la dernière version ou spécifier une autre version.
npm install --save jquery@3.2.1
installer expose-loader
comme une dépendance de développement si elle n'est pas déjà installée.
npm install expose-loader --save-dev
configurer Webpack pour charger et exposer jQuery pour nous.
// webpack.config.js
const webpack = require('webpack')
module.exports = {
entry: [
// entry bits
],
output: {
// output bits
},
module: {
rules: [
// any other rules
{
// Exposes jQuery for use outside Webpack build
test: require.resolve('jquery'),
use: [{
loader: 'expose-loader',
options: 'jQuery'
},{
loader: 'expose-loader',
options: '$'
}]
}
]
},
plugins: [
// Provides jQuery for other JS bundled with Webpack
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
}
cela fonctionne dans webpack 3:
dans le webpack.config.Babel.fichier js:
resolve: {
alias: {
jquery: "jquery/src/jquery"
},
....
}
et utiliser ProvidePlugin
new webpack.ProvidePlugin({
'$': 'jquery',
'jQuery': 'jquery',
})
j'ai essayé certaines des réponses fournies mais aucune ne semblait fonctionner. Puis j'ai essayé ceci:
new webpack.ProvidePlugin({
'window.jQuery' : 'jquery',
'window.$' : 'jquery',
'jQuery' : 'jquery',
'$' : 'jquery'
});
Semble fonctionner quelle que soit la version que j'utilise
la meilleure solution que j'ai trouvée était:
https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059
en gros, vous devez inclure une variable fictive sur les typographies.D. ts, supprimez tout "importer * comme $ de 'jquery" de votre code, puis ajoutez manuellement une balise à jQuery script à votre html SPA. De cette façon, webpack ne sera pas sur votre chemin, et vous devriez être en mesure d'accéder à la même variable jQuery globale dans tous les vos scripts.
Cela fonctionne pour moi sur le webpack.config.js
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
dans un autre javascript ou dans HTML ajouter:
global.jQuery = require('jquery');
modifier: parfois, vous voulez utiliser webpack simplement comme un module bundler pour un projet web simple - pour garder votre propre code organisé. La solution suivante est pour ceux qui veulent juste qu'une bibliothèque externe fonctionne comme prévu à l'intérieur de leurs modules - sans passer beaucoup de temps à plonger dans les configurations webpack. (Révisé après -1)
solution rapide et simple (es6) si vous êtes encore en difficulté ou si vous voulez éviter les externes config / plugin webpack config:
<script src="cdn/jquery.js"></script>
<script src="cdn/underscore.js"></script>
<script src="etc.js"></script>
<script src="bundle.js"></script>
dans un module:
const { jQuery: $, Underscore: _, etc } = window;
dans votre webpack.config.Ajouter ci-dessous:
var webpack = require("webpack");
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
],
installer jQuery en utilisant npm:
$ npm i jquery --save
Dans l'app.ajouter les lignes suivantes:
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
ça a marché pour moi. :)