Używam Webpack w mojej aplikacji, w której tworzę dwa punkty wejścia - bundle.js dla wszystkich moich plików / kodów JavaScript i vendors.js dla wszystkich bibliotek takich jak jQuery i React. Co mam zrobić, aby korzystać z wtyczek, które mają zależności jQuery i chcę mieć je również w vendors.js? Co jeśli te wtyczki mają wiele zależności?
Obecnie próbuję użyć tej wtyczki jQuery tutaj - https://github.com/mbklein/jquery-elastic . Dokumentacja pakietu Webpack wspomina o opcji Plugin i moduł ładujący import. Korzystałem z programu enablePlugin, ale obiekt jQuery wciąż nie jest dostępny. Oto jak wygląda mój plik 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;
Mimo to nadal wyświetla błąd w konsoli przeglądarki:
Uncaught ReferenceError: jQuery nie jest zdefiniowany
Podobnie, gdy używam modułu ładującego import, zgłasza błąd,
wymaganie nie jest zdefiniowane ”
w tej linii:
var jQuery = require("jquery")
Mogę jednak użyć tej samej wtyczki, jeśli nie dodam jej do mojego pliku vendors.js i zamiast tego wymagam jej w normalny sposób AMD, ponieważ dołączam inne pliki kodu JavaScript, takie jak-
define(
[
'jquery',
'react',
'../../common-functions',
'../../libs/jquery.elastic.source'
],function($,React,commonFunctions){
$("#myInput").elastic() //It works
});
Ale nie chcę tego robić, ponieważ oznaczałoby to, że plik jquery.elastic.source.js znajduje się w pakiecie wraz z moim kodem JavaScript w pakiecie.js i chcę, aby wszystkie moje wtyczki jQuery znajdowały się w pakiecie vendors.js. Jak mam to osiągnąć?
źródło
Odpowiedzi:
Mieszałeś różne podejścia do włączania starszych modułów dostawców. Oto jak sobie z tym poradzę:
1. Preferuj niezminimalizowane CommonJS / AMD
dist
Większość modułów łączy
dist
wersję w swoimmain
polupackage.json
. Chociaż jest to przydatne dla większości programistów, w przypadku pakietu WWW lepiej jest dokonać aliasusrc
wersji, ponieważ w ten sposób pakiet może lepiej zoptymalizować zależności (np. Podczas korzystania zDedupePlugin
).Jednak w większości przypadków
dist
wersja działa również dobrze.2. Użyj
ProvidePlugin
do wstrzyknięcia niejawnych globałówWiększość starszych modułów polega na obecności określonych globałów, takich jak wtyczki jQuery na
$
lubjQuery
. W tym scenariuszu możesz skonfigurować pakiet WWW, aby byłvar $ = require("jquery")
on przygotowywany za każdym razem, gdy napotka globalny$
identyfikator.3. Skorzystaj z modułu ładującego import, aby skonfigurować
this
Niektóre starsze moduły polegają na
this
byciuwindow
obiektem. Staje się to problemem, gdy moduł jest wykonywany w kontekście CommonJS, gdziethis
jest równymodule.exports
. W takim przypadku możesz zastąpićthis
program ładujący import .Uruchom
npm i imports-loader --save-dev
i wtedyModuł importujący może także służyć do ręcznego wstrzykiwania zmiennych wszelkiego rodzaju. Ale przez większość czasu
ProvidePlugin
jest to bardziej przydatne, jeśli chodzi o ukryte globale.4. Użyj modułu importującego, aby wyłączyć AMD
Istnieją moduły obsługujące różne style modułów, takie jak AMD, CommonJS i starsze wersje. Jednak przez większość czasu najpierw sprawdzają,
define
a następnie używają dziwnego kodu do eksportowania właściwości. W takich przypadkach może pomóc wymusić ścieżkę CommonJS przez ustawieniedefine = false
.5. Użyj programu ładującego skrypty do globalnego importowania skryptów
Jeśli nie interesują Cię zmienne globalne i po prostu chcesz, aby starsze skrypty działały, możesz także użyć programu ładującego skrypty. Wykonuje moduł w kontekście globalnym, tak jakbyś umieścił je za pomocą
<script>
znacznika.6. Użyj,
noParse
aby uwzględnić duże odległościJeśli nie ma wersji modułu AMD / CommonJS i chcesz dołączyć
dist
, możesz oflagować ten moduł jakonoParse
. Następnie webpack po prostu obejmie moduł bez analizowania go, co można wykorzystać do poprawy czasu kompilacji. Oznacza to, że żadna funkcja wymagająca AST , taka jakProvidePlugin
, nie będzie działać.źródło
ProvidePlugin
Jest stosowana na wszystkich wystąpień podanych identyfikatorów we wszystkich plikach.imports-loader
Mogą być stosowane tylko w określonych plików, ale nie powinno się używać zarówno do tych samych zmiennych / zależnościami.$
zmiennej globalnej ."module": { "loaders": [ { test: require.resolve("jquery"), loader: "expose?$!expose?jQuery" },
i działało dobrze.Aby uzyskać globalny dostęp do jquery, istnieje kilka opcji. W moim najnowszym projekcie pakietu internetowego chciałem globalnego dostępu do jquery, więc do moich deklaracji wtyczek dodałem następujące elementy:
Oznacza to, że jquery jest dostępne z poziomu kodu źródłowego JavaScript poprzez globalne odwołania $ i jQuery.
Oczywiście musisz także zainstalować jquery za pośrednictwem npm:
Przykładem takiego podejścia jest rozwidlenie mojej aplikacji na github
źródło
ProvidePlugin
proponowane przez Ciebie rozwiązanie zostało już zaproponowane?./~/jQuery/dist/jquery.js There is another module with an equal name when case is ignored.
i to samo z./~/jquery/dist/jquery.js
'window.jQuery': 'jquery'
do tej listy, aby załadować pakiet npm ms-signalr-client. Włożyłem również'window.$': 'jquery'
dla dobrego :)Nie wiem, czy dobrze rozumiem, co próbujesz zrobić, ale musiałem użyć wtyczek jQuery, które wymagały, aby jQuery znajdowało się w kontekście globalnym (okno) i umieściłem w moim
entry.js
:Muszę tylko wymagać, gdziekolwiek chcę
jqueryplugin.min.js
iwindow.$
jest rozszerzony o wtyczkę zgodnie z oczekiwaniami.źródło
Sprawiłem, że wszystko działało ładnie podczas wyświetlania
$
ijQuery
jako zmienne globalne w Webpack 3.8.1 i następnych.Zainstaluj jQuery jako zależność projektu. Możesz pominąć
@3.2.1
instalację najnowszej wersji lub podać inną wersję.Zainstaluj
expose-loader
jako zależność programistyczną, jeśli jeszcze nie została zainstalowana.Skonfiguruj Webpack, aby ładował i ujawniał dla nas jQuery.
źródło
expose-loader
, aby działał poprawnienpm install expose-loader --save-dev
expose-loaded
Zrobił to dla mnie. W czasie kompilacji nie wystąpił błąd, ale w narzędziach dla programistów Chrome. To już rozwiązane.Dodaj to do tablicy wtyczek w webpack.config.js
następnie normalnie wymagaj jquery
Jeśli ból nadal występuje, aby inne skrypty go widziały, spróbuj jawnie umieścić go w kontekście globalnym za pośrednictwem (w pozycji js)
źródło
W pliku webpack.config.js dodaj poniżej:
Zainstaluj jQuery przy użyciu npm:
W pliku app.js dodaj poniższe wiersze:
To zadziałało dla mnie. :)
źródło
Wypróbowałem niektóre z dostarczonych odpowiedzi, ale żadna z nich nie działała. Potem spróbowałem:
Wydaje się działać bez względu na to, której wersji używam
źródło
$
pliku wymaganego poza pakietem WWW, zostanie on niezdefiniowany.Działa to w pakiecie internetowym 3:
w pliku webpack.config.babel.js:
I użyj ProvidePlugin
źródło
Najlepsze rozwiązanie, jakie znalazłem, to:
https://github.com/angular/angular-cli/issues/5139#issuecomment-283634059
Zasadniczo musisz dołączyć zmienną fikcyjną do typings.d.ts, usunąć wszelkie „import * as $ z„ jquery ”z kodu, a następnie ręcznie dodać znacznik do skryptu jQuery do html SPA. W ten sposób webpack nie będzie na twojej drodze i powinieneś mieć dostęp do tej samej globalnej zmiennej jQuery we wszystkich swoich skryptach.
źródło
Działa to dla mnie na webpack.config.js
w innym javascript lub w HTML dodaj:
źródło
Edycja: Czasami chcesz używać pakietu web po prostu jako programu pakującego moduły do prostego projektu internetowego - w celu uporządkowania własnego kodu. Poniższe rozwiązanie jest przeznaczone dla tych, którzy chcą tylko, aby biblioteka zewnętrzna działała zgodnie z oczekiwaniami w swoich modułach - bez poświęcania dużo czasu na konfigurowanie pakietu WWW. (Edytowane po -1)
Szybkie i proste rozwiązanie (es6), jeśli nadal masz problemy lub chcesz uniknąć konfiguracji zewnętrznej / dodatkowej konfiguracji wtyczki pakietu sieciowego:
wewnątrz modułu:
źródło