Webpack ProvidePlugin mi harici mi?


84

Backbone.js ile Webpack kullanma fikrini araştırıyorum .

Hızlı başlangıç ​​kılavuzunu takip ettim ve Webpack'in nasıl çalıştığına dair genel bir fikrim var, ancak jquery / omurga / alt çizgi gibi bağımlılık kitaplığının nasıl yükleneceği konusunda emin değilim.

Harici olarak mı yüklenmeli <script>yoksa bu, Webpack'in RequireJS'in altlığı gibi işleyebileceği bir şey mi?

Göre webpack doc: modüllerini shimming , ProvidePluginve externalsbu ilişkili olduğu görünmektedir (böyledir bundle!yükleyici yerde) ama hangi ne zaman kullanılacağını bilemiyorum.

Teşekkürler

Yanıtlar:


153

Her ikisi de mümkündür: a ile kitaplıkları dahil edebilirsiniz <script>(yani bir CDN'den bir kitaplık kullanmak için) veya bunları oluşturulan pakete dahil edebilirsiniz.

<script>Etiket aracılığıyla yüklerseniz , externalsyazmaya izin verme seçeneğini kullanabilirsiniz.require(...) , modüllerinize .

CDN'den kitaplık örneği:

<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");

Pakette bulunan kitaplık örneği:

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(Ücretsiz) değişkenlere modüllerini eşleştirebilirsiniz. Eğer tanımlayabiliriz Yani: "Her zaman (ücretsiz) değişkeni kullanan xyzsen (webpack) belirlesin bir modül içerisindeki xyziçin require("abc")."

Olmadan örnek ProvidePlugin:

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

Örnek ProvidePlugin:

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

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

Özet:

  • CDN'den Kitaplık: <script>Etiket ve externalsseçeneği kullanın
  • Dosya sisteminden kitaplık: Kitaplığı pakete dahil edin. ( resolveKitaplığı bulmak için seçenekleri değiştirebilirsiniz )
  • externals: Global değişkenleri modül olarak kullanılabilir hale getirin
  • ProvidePlugin: Modülleri modüllerin içinde serbest değişkenler olarak kullanılabilir hale getirin

Eklemek gerekir newönce webpack.ProvidePlugin webpack.github.io/docs/list-of-plugins.html
MK Yung

Neden komut dosyası yükleyiciyi kullanmıyorsunuz? @Dtothefp'in açıkladığı gibi bu çok daha kolay
timaschew

Webpack.config dosyam javascript adlı bir klasördeyse ve içinde jquery dosyamla birlikte vendor adında bir klasörüm varsa. yol olmamalı. çözümleyin: {alias: {jquery: "vendor / jquery-1.10.2.js"}}.
me-me

3
Sadece takma ad seçeneğine mutlak bir yol verin. Göreli bir yol iletirseniz, bu, web paketi 1'deki gerekli / içe aktarmanın konumuna bağlıdır. Webpack 2'de, webpack.config.js dosyası resp. bağlam seçeneği.
Tobias K.

@TobiasK. Mutlak bir yol, varsayılan dışa aktarmalarla işbirliği yapmaz. Dosyaların {__esModule: true, default: MY_DEFAULT_EXPORT}yerine bir nesne alıyorum MY_DEFAULT_EXPORT.
mgol

26

Unutulmaması gereken güzel bir şey ProvidePluginde, externalsmülk ile birlikte kullanırsanız, jQueryweb paketi modülünüzün kapanışına açıkça gerek kalmadan geçmenize izin vereceğidir require. Bu, eski kodu birçok farklı dosyaya referansla yeniden düzenlemek için yararlı olabilir $.

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

şimdi index.js'de

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

aşağıdaki gibi webpackBootstrapkapanışa geçirilen derlenmiş bir çıktıya sahip olacak :

/******/ ([
/* 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;

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

Bu nedenle, bunun CDN'den $global / pencereye başvurduğunu jQueryancak kapanışa geçirildiğini görebilirsiniz. Bunun amaçlanan işlevsellik mi yoksa şanslı bir hack mi olduğundan emin değilim, ancak kullanım durumum için iyi çalışıyor gibi görünüyor.


her iki eklentiye de ihtiyacınız yoktu require/import. $işe yarayacak çünkü ne olursa olsun küresel kapsama ulaşacak. Bu ProviderPlugin, AST'nin ayrıştırılmasını gerektirir, bu nedenle pahalı bir eklentidir ve yapım sürenize gözle görülür şekilde eklenir. Yani temelde bir israf.
faceyspacey.com

@dtohefp bu cevap bir nimettir. Modülü dışsallara eklemediğim sürece neden ProvidePluginbir nesneyi döndürdüğünü açıklayabilir misiniz myModule.default? Doğrudan bir ilişki olacağını asla bilmiyordum.
Slbox

11

Bunun eski bir gönderi olduğunu biliyorum, ancak web paketi komut dosyası yükleyicisinin bu durumda da yararlı olabileceğini belirtmenin faydalı olacağını düşündüm. Web paketi belgelerinden:

"script: Bir JavaScript dosyasını genel bağlamda bir kez çalıştırır (komut dosyası etiketinde olduğu gibi), gerekenler ayrıştırılmaz."

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

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

Bunu, JS satıcı dosyalarını ve uygulama dosyalarını bir arada birleştiren eski yapı işlemlerini taşırken özellikle yararlı buldum. Bir uyarı kelimesi, komut dosyası yükleyicinin yalnızca aşırı yükleme yoluyla çalışıyor gibi göründüğü require()ve bir webpack.config dosyasında belirtilerek anlayabildiğim kadarıyla çalışmadığıdır. Birçoğu aşırı requireyüklemenin kötü bir uygulama olduğunu iddia etse de, satıcıyı ve uygulama komut dosyasını tek bir pakette birleştirmek ve aynı zamanda ek web paketi paketlerine takılması gerekmeyen JS Globals'ı ortaya çıkarmak için oldukça yararlı olabilir. Örneğin:

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

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

Bu, $ .cookie, History ve moment'i bu paketin içinde ve dışında küresel olarak kullanılabilir hale getirir ve bu satıcı kitaplıklarını main.js komut dosyasıyla ve tüm require d dosyalarıyla .

Ayrıca, bu teknikle yararlı olan:

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

Bower kullanan, mainher required libraries package.json dosyasındaki dosyaya bakacaktır . Yukarıdaki örnekte History.js mainbelirtilmiş bir dosyaya sahip değildir , bu nedenle dosyanın yolu gereklidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.