Správa závislosti zásuvného modulu jQuery v aplikácii Webpack
Vo svojej aplikácii používam Webpack, v ktorom mám vytvorené dva vstupné body - bundle.js pre všetky súbory/kódy JavaScriptu a vendors.js pre všetky knižnice, ako je jQuery a React. Čo mám urobiť, aby som mohol používať zásuvné moduly, ktoré majú ako svoje závislosti jQuery a chcem ich mať aj vo vendors.js? Čo ak majú tieto zásuvné moduly viacero závislostí?
Momentálne sa snažím používať tento plugin jQuery tu - https://github.com/mbklein/jquery-elastic. V dokumentácii Webpack sa spomína providePlugin a imports-loader. Použil som providePlugin, ale objekt jQuery stále nie je k dispozícii. Takto vyzerá môj 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;
Ale napriek tomu to stále hádže chybu do konzoly prehliadača:
Uncaught ReferenceError: jQuery is not defined
Podobne, keď použijem import-loader, vyhodí to chybu,
require is not defined'
v tomto riadku:
var jQuery = require("jquery")
Mohol by som však použiť ten istý zásuvný modul, keď ho nepridám do súboru vendors.js a namiesto toho ho vyžadujem normálnym spôsobom AMD, ako keď zahŕňam svoje ostatné súbory s kódom JavaScript, ako napríklad-
define(
[
'jquery',
'react',
'../../common-functions',
'../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
$("#myInput").elastic() //It works
});
Ale to nie je to, čo chcem urobiť, pretože by to znamenalo, že jquery.elastic.source.js je spolu s mojím kódom JavaScript v zväzku bundle.js a ja chcem, aby všetky moje zásuvné moduly jQuery boli vo zväzku vendors.js. Ako to mám teda dosiahnuť?
Zmiešali ste rôzne prístupy, ako zahrnúť staršie moduly dodávateľa. Ja by som to riešil takto:
1. Uprednostnite nezminifikovaný CommonJS/AMD pred
dist
Väčšina modulov spája verziu
dist
v polimain
svojho súborupackage.json
. Aj keď je to pre väčšinu vývojárov užitočné, pre webpack je lepšie aliasovať verziusrc
, pretože takto dokáže webpack lepšie optimalizovať závislosti (napr. pri použitíDedupePlugin
).Vo väčšine prípadov však rovnako dobre funguje aj verzia
dist
.2. Na injektovanie implicitných globálov použite príkaz
ProvidePlugin
Väčšina starších modulov sa spolieha na prítomnosť špecifických globálov, ako to robia pluginy jQuery na
$
alebojQuery
. V tomto prípade môžete nakonfigurovať webpack tak, aby predvyplnilvar $ = require("jquery")
vždy, keď narazí na globálny identifikátor$
.3. Pomocou príkazu imports-loader nakonfigurujte
this
Niektoré staršie moduly sa spoliehajú na to, že
this
je objektwindow
. To sa stáva problémom, keď je modul spustený v kontexte CommonJS, kde sathis
rovnámodule.exports
. V takom prípade môžete prepísaťthis
pomocou imports-loader.Spustite
npm i imports-loader --save-dev
a potomImport-loader možno použiť aj na ručné injektovanie premenných všetkých druhov. Väčšinou je však
ProvidePlugin
užitočnejší, keď ide o implicitné globály.4. Použite imports-loader na vypnutie AMD
Existujú moduly, ktoré podporujú rôzne štýly modulov, napríklad AMD, CommonJS a legacy. Väčšinou však najprv skontrolujú, či je v nich
define
, a potom použijú nejaký bizarný kód na export vlastností. V týchto prípadoch by mohlo pomôcť vynútiť cestu CommonJS nastavenímdefine = false
.5. Použite script-loader na globálny import skriptov
Ak sa nestaráte o globálne premenné a chcete, aby fungovali len staršie skripty, môžete použiť aj skript-loader. Spustí modul v globálnom kontexte, rovnako ako keby ste ich zahrnuli prostredníctvom značky
<script>
.6. Použitie
noParse
na zahrnutie veľkých distAk neexistuje verzia modulu AMD/CommonJS a chcete zahrnúť
dist
, môžete tento modul označiť akonoParse
. Potom webpack len zahrnie modul bez jeho rozboru, čo sa dá použiť na zlepšenie času zostavenia. To znamená, že žiadna funkcia vyžadujúca AST, ako napríkladProvidePlugin
, nebude fungovať.Pre globálny prístup k jquery existuje niekoľko možností. V mojom najnovšom projekte Webpack som chcel globálny prístup k jquery, takže som do deklarácií zásuvných modulov pridal nasledujúce možnosti:
To potom znamená, že jquery je prístupné zo zdrojového kódu JavaScriptu prostredníctvom globálnych odkazov $ a jQuery.
Samozrejme, musíte mať nainštalované aj jquery prostredníctvom npm:
Pre funkčný príklad tohto prístupu neváhajte forknúť moju aplikáciu na github.
Neviem, či dobre rozumiem tomu, čo sa snažíte urobiť, ale musel som použiť pluginy jQuery, ktoré vyžadovali, aby jQuery bolo v globálnom kontexte (okno) a do môjho súboru
entry.js
som vložil nasledujúce:The I just have to require wherever I want the
jqueryplugin.min.js
awindow.$
je rozšírený o plugin podľa očakávania.