2014-04-26 30 views
71

Odkrywam pomysł użycia Webpack z Backbone.js.Webpack ProvidePlugin vs externals?

Śledziłem przewodnik szybkiego uruchamiania i mam ogólne pojęcie o działaniu Webpacka, ale nie mam pojęcia, jak załadować bibliotekę zależności, takich jak jquery/backbone/underscore.

Czy należy je ładować zewnętrznie za pomocą <script>, czy jest to coś, co Webpack może poradzić sobie z podkładką RequireJS?

Według webpack doc: shimming modules, ProvidePlugin i externals wydają się być podobne do tego (tak jest bundle! ładowarka gdzieś), ale nie mogę dowiedzieć się, kiedy używać które.

Dzięki

Odpowiedz

134

To zarówno możliwe: Można dołączyć bibliotek z <script> lub zawierają je w generowanej wiązki (tj użyć biblioteki z CDN..).

Jeśli załadujesz go za pomocą znacznika <script>, możesz użyć opcji externals, aby umożliwić zapisanie require(...) w swoich modułach.

Przykład z biblioteki z CDN:

<script src="https://code.jquery.com/jquery-git2.min.js"></script> 

// the artifial module "jquery" exports the global var "jQuery" 
externals: { jquery: "jQuery" } 

// inside any module 
var $ = require("jquery"); 

Przykład z biblioteki zawarte w zestawie:

copy `jquery-git2.min.js` to your local filesystem 

// make "jquery" resolve to your local copy of the library 
// i. e. through the resolve.alias option 
resolve: { alias: { jquery: "/path/to/jquery-git2.min.js" } } 

// inside any module 
var $ = require("jquery"); 

ProvidePlugin może odwzorowywać moduły do ​​(wolnych) zmiennych. Możesz więc zdefiniować: "Za każdym razem, gdy używam (wolnej) zmiennej xyz wewnątrz modułu, który (pakiet sieciowy) powinien ustawić xyz na require("abc")."

Przykład bez ProvidePlugin:

// You need to require underscore before you can use it 
var _ = require("underscore"); 
_.size(...); 

Przykład z ProvidePlugin:

plugins: [ 
    new webpack.ProvidePlugin({ 
    "_": "underscore" 
    }) 
] 

// If you use "_", underscore is automatically required 
_.size(...) 

Podsumowanie:

  • bibliotekę CDN Use <script> znaczników i externals opcja
  • Biblioteka z systemu plików: dołącz bibliotekę do pakietu. (Może modyfikować resolve opcji, aby znaleźć Library)
  • externals: Sprawdź globalne Vars dostępny jako moduł
  • ProvidePlugin: Sprawdź moduły dostępne jako zmiennych wolnych modułów wewnątrz
+0

Należy dodać 'new' przed' webpack.ProvidePlugin' http://webpack.github.io/docs/list-of-plugins.html –

+0

Tak, dzięki. Naprawiłem to. –

+0

Dlaczego po prostu nie używać skryptowego programu ładującego? Jest to znacznie łatwiejsze, jak wyjaśnił @ dtothefp – timaschew

11

Wiem, że to stary post, ale myśl warto wspomnieć, że program ładujący skrypt sieciowy może być również użyteczny w tym przypadku. Z dokumentacji pakietów:

"skrypt: wykonuje jeden raz plik JavaScript w kontekście globalnym (jak w znaczniku skryptu), wymagania nie są przetwarzane."

http://webpack.github.io/docs/list-of-loaders.html

https://github.com/webpack/script-loader

Znalazłem to szczególnie przydatne podczas migracji starszych budować procesy Concat plików dostawcy JS i aplikacja Pliki razem. Słowo ostrzeżenia jest to, że ładowarka scenariusz wydaje się tylko do pracy przez przeciążanie require() i nie działa tak daleko, jak mogę stwierdzić, podając go w pliku webpack.config. Chociaż wielu twierdzi, że przeciążenie require jest złym zwyczajem, może być całkiem przydatne do zawarcia skryptu dostawcy i aplikacji w jednym pakiecie, oraz jednocześnie eksponując JS Globals, które nie muszą być przesuwane w pakiecie Webpack es. Na przykład:

require('script!jquery-cookie/jquery.cookie'); 
require('script!history.js/scripts/bundled-uncompressed/html4+html5/jquery.history'); 
require('script!momentjs'); 

require('./scripts/main.js'); 

uczyniłoby to $ .cookie, historia, i chwila globalnie dostępny wewnątrz i na zewnątrz tej wiązki i wiązki te bibliotekami dostawcy z skryptu main.js a wszystko to jest require d plików.

również przydatna z tej techniki jest:

resolve: { 
    extensions: ["", ".js"], 
    modulesDirectories: ['node_modules', 'bower_components'] 
}, 
plugins: [ 
    new webpack.ResolverPlugin(
    new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"]) 
    ) 
] 

który korzysta altana, będą patrzeć na pliku main w każdym require d bibliotek package.json. W powyższym przykładzie plik History.js nie ma podanego pliku main, dlatego konieczne jest podanie ścieżki do pliku.

21

coś fajnego, aby pamiętać, że jeśli używasz ProvidePlugin w połączeniu z właściwością externals pozwoli Ci mieć jQuery przeszedł w swoim zamknięciu modułu WebPACK bez konieczności jawnie require to. Może to być przydatne do refaktoryzacji starszego kodu z wieloma różnymi plikami z odniesieniami do $.

//webpack.config.js 
module.exports = { 
    entry: './index.js', 
    output: { 
    filename: '[name].js' 
    }, 
    externals: { 
    jquery: 'jQuery' 
    }, 
    plugins: [ 
    new webpack.ProvidePlugin({ 
     $: 'jquery', 
    }) 
    ] 
}; 

teraz w index.js

console.log(typeof $ === 'function'); 

będzie miał skompilowany wyjście z czymś takim poniżej przeszedł do webpackBootstrap Zamknięcie:

/******/ ([ 
/* 0 */ 
/***/ function(module, exports, __webpack_require__) { 

    /* WEBPACK VAR INJECTION */(function($) { 
     console.log(typeof $ === 'function'); 

    /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(1))) 

/***/ }, 
/* 1 */ 
/***/ function(module, exports, __webpack_require__) { 

    module.exports = jQuery; 

/***/ } 
/******/ ]) 

Zatem widać, że $ odwołuje globalne/okno jQuery z CDN, ale jest przekazywane do zamknięcia. Nie jestem pewien, czy jest to zamierzona funkcjonalność, czy szczęśliwy hack, ale wygląda na to, że działa dobrze w moim przypadku użycia.