J'utilise Webpack dans mon application, dans laquelle je crée deux points d'entrée: bundle.js pour tous mes fichiers/codes JavaScript et vendors.js pour toutes les bibliothèques telles que jQuery et React. Que dois-je faire pour utiliser les plugins qui ont jQuery comme dépendances et je veux les avoir aussi dans vendors.js? Que se passe-t-il si ces plugins ont plusieurs dépendances?
Actuellement, j'essaie d'utiliser ce plugin jQuery ici - https://github.com/mbklein/jquery-elastic . La documentation Webpack mentionne ProvidePlugin et imports-loader. J'ai utilisé offerPlugin, mais l'objet jQuery n'est toujours pas disponible. Voici à quoi ressemble mon webpack.config.js-
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;
Malgré cela, une erreur est toujours générée dans la console du navigateur:
Uncaught ReferenceError: jQuery n'est pas défini
De la même façon, quand j'utilise imports-loader, cela génère une erreur,
require n'est pas défini '
dans cette ligne:
var jQuery = require("jquery")
Cependant, je pourrais utiliser le même plugin lorsque je ne l'ajoute pas à mon fichier vendors.js mais que je l'exige à la manière habituelle d'AMD, comme pour inclure 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 voudrait dire que jquery.elastic.source.js est fourni avec mon code JavaScript dans bundle.js, et je veux que tous mes plugins jQuery soient dans le paquet vendors.js. Alors, comment puis-je y parvenir?
Vous avez mélangé différentes approches pour inclure des modules de fournisseur hérités. Voici comment je l'aborderais:
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’aliaser la version src
car de cette manière, webpack est en mesure d’optimiser les dépendances (par exemple, lorsqu’on utilise DedupePlugin
).
// webpack.config.js
module.exports = {
...
resolve: {
alias: {
jquery: "jquery/src/jquery"
}
}
};
Cependant, dans la plupart des cas, la version dist
fonctionne également très bien.
ProvidePlugin
pour injecter des globals implicitesLa plupart des modules existants s'appuient sur la présence de globaux spécifiques, comme les plugins jQuery sur $
ou jQuery
. Dans ce scénario, vous pouvez configurer Webpack pour ajouter var $ = require("jquery")
chaque fois qu'il rencontre l'identificateur global $
.
var webpack = require("webpack");
...
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
this
Certains modules hérités reposent sur le fait que this
soit l’objet window
. Cela devient un problème lorsque le module est exécuté dans un contexte CommonJS où this
est égal à module.exports
. Dans ce cas, vous pouvez remplacer this
par imports-loader .
Exécutez npm i imports-loader --save-dev
puis
module: {
loaders: [
{
test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
loader: "imports-loader?this=>window"
}
]
}
Le imports-loader peut également être utilisé pour injecter manuellement des variables de toutes sortes. Mais la plupart du temps, ProvidePlugin
est plus utile en ce qui concerne les globals implicites.
Certains modules prennent en charge différents styles de modules, tels que AMD, CommonJS et Legacy. Cependant, la plupart du temps, ils vérifient d'abord define
, puis utilisent un code bizarre pour exporter les propriétés. Dans ces cas, il pourrait être utile de forcer le chemin CommonJS en définissant define = false
.
module: {
loaders: [
{
test: /[\/\\]node_modules[\/\\]some-module[\/\\]index\.js$/,
loader: "imports-loader?define=>false"
}
]
}
Si vous ne vous souciez pas des variables globales et souhaitez simplement que les scripts hérités fonctionnent, vous pouvez également utiliser le chargeur de scripts. Il exécute le module dans un contexte global, comme si vous les aviez inclus via la balise <script>
.
noParse
pour inclure les grandes distributionsLorsqu'il n'existe pas de version AMD/CommonJS du module et que vous souhaitez inclure dist
, vous pouvez le marquer en tant que noParse
. Ensuite, webpack inclura simplement le module sans l’analyser, ce qui peut être utilisé pour améliorer le temps de compilation. Cela signifie que toute fonctionnalité nécessitant le AST , comme le ProvidePlugin
, ne fonctionnera pas.
module: {
noParse: [
/[\/\\]node_modules[\/\\]angular[\/\\]angular\.js$/
]
}
Pour un accès global à jquery, plusieurs options existent. Dans mon dernier projet de pack Web, je voulais un accès global à jquery. J'ai donc ajouté ce qui suit à mes déclarations de plugins:
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]
Cela signifie alors que jquery est accessible depuis le code source JavaScript via les références globales $ et jQuery.
Bien entendu, vous devez également avoir installé jquery via npm:
$ npm i jquery --save
Pour un exemple concret de cette approche, n'hésitez pas à ajouter mon application github
Je ne sais pas si je comprends très bien ce que vous essayez de faire, mais je devais 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.$ = $;
Le je dois juste demander où je veux le jqueryplugin.min.js
et window.$
est étendu avec le plugin comme prévu.
Les choses fonctionnent bien tout en exposant $
et jQuery
en tant que variables globales avec Webpack 3.8.1 et les suivants.
Installez jQuery en tant que 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 [email protected]
Installez expose-loader
en tant que dépendance de développement, si ce n’est déjà fait.
npm install expose-loader --save-dev
Configurez 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'
})
]
}
Ajoutez ceci à votre tableau de plugins dans webpack.config.js
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
'window.$': 'jquery',
})
alors besoin de jquery normalement
require('jquery');
Si douleur persiste pour que d'autres scripts le voient, essayez explicitement de le placer dans le contexte global via (dans l'entrée js)
window.$ = jQuery;
Dans votre fichier webpack.config.js, ajoutez ci-dessous:
var webpack = require("webpack");
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
],
Installez jQuery en utilisant npm:
$ npm i jquery --save
Dans le fichier app.js, ajoutez les lignes suivantes:
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
Cela a fonctionné pour moi. :)
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
Cela fonctionne dans webpack 3:
dans le fichier webpack.config.babel.js:
resolve: {
alias: {
jquery: "jquery/src/jquery"
},
....
}
Et utilisez ProvidePlugin
new webpack.ProvidePlugin({
'$': 'jquery',
'jQuery': 'jquery',
})
Cela fonctionne pour moi sur le webpack.config.js
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery'
}),
dans un autre javascript ou HTML, ajoutez:
global.jQuery = require('jquery');
La meilleure solution que j'ai trouvée était:
https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059
Fondamentalement, vous devez inclure une variable factice sur le fichier typings.d.ts, supprimer de votre code toute "importation * en tant que $ de 'jquery", puis ajouter manuellement une balise au script jQuery dans votre code html SPA. Ainsi, WebPack ne vous gênera pas et vous devriez pouvoir accéder à la même variable globale jQuery dans tous vos scripts.
Éditer: Parfois, vous voulez utiliser webpack simplement comme un bundle de modules pour un projet web simple - pour garder votre propre code organisé. La solution suivante est destinée à ceux qui souhaitent simplement qu'une bibliothèque externe fonctionne comme prévu dans leurs modules, sans passer beaucoup de temps à plonger dans les configurations Webpack. (Edité après -1)
Solution simple et rapide (es6) si vous avez encore du mal à éviter les configurations externes/externes avec le 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>
à l'intérieur d'un module:
const { jQuery: $, Underscore: _, etc } = window;