Webpack ile global değişkeni tanımlayın


138

Webpack ile global bir değişken tanımlamak mümkün müdür:

var myvar = {};

Gördüğüm tüm örnekler harici dosya kullanıyordu require("imports?$=jquery!./file.js")

Yanıtlar:


272

Globallere yaklaşmanın birkaç yolu vardır:

1) Değişkenlerinizi bir modüle koyun.

Webpack modülleri yalnızca bir kez değerlendirir, böylece örneğiniz global kalır ve modülden modüle değişiklikler yapar. Yani a gibi bir şey oluşturursanız globals.jsve tüm globallerinizin bir nesnesini dışa aktarırsanız import './globals', bu globallere okuyabilir / yazabilirsiniz. Bir modüle içe aktarabilir, bir işlevden nesnede değişiklikler yapabilir ve başka bir modüle aktarabilir ve bu değişiklikleri bir işlevde okuyabilirsiniz. Ayrıca olayların gerçekleştiğini unutmayın. Webpack önce tüm içe aktarmaları alıp yükler entry.js. Sonra yürütür entry.js. Bu yüzden küresellere okuduğunuz / yazdığınız yer önemlidir. Bir modülün kök kapsamından mı yoksa daha sonra adlandırılan bir fonksiyondan mı?

Not : Örneğin newher seferinde olmasını istiyorsanız, bir ES6 sınıfı kullanın . Geleneksel olarak JS'de sınıfları (nesneler için küçük harflerin aksine)
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()

2) Webpack'in ProvidePlugin'i

Bunu Webpack'in ProvidePlugin (her modülü ve yalnızca gerçekten kullandığınız modülleri bir değişken olarak kullanılabilir kılan) kullanarak nasıl yapabileceğiniz aşağıda açıklanmıştır. Bu, import Bar from 'foo'tekrar tekrar yazmaya devam etmek istemediğinizde kullanışlıdır . Ya da jQuery veya lodash gibi bir paketi buraya global olarak getirebilirsiniz (ancak Webpack'in Dış Özelliklerine bakabilirsiniz ).

Adım 1) Herhangi bir modül oluşturun. Örneğin, küresel bir yardımcı program seti kullanışlı olacaktır:

utils.js

export function sayHello () {
  console.log('hello')
}

Adım 2) Modülü takma ve ProvidePlugin'e ekleyin:

webpack.config.js

var webpack = require("webpack");
var path = require("path");

// ...

module.exports = {

  // ...

  resolve: {
    extensions: ['', '.js'],
    alias: {
      'utils': path.resolve(__dirname, './utils')  // <-- When you build or restart dev-server, you'll get an error if the path to your utils.js file is incorrect.
    }
  },

  plugins: [

    // ...

    new webpack.ProvidePlugin({
      'utils': 'utils'
    })
  ]  

}

Şimdi sadece utils.sayHello()herhangi bir js dosyasını arayın ve çalışması gerekir. Webpack ile kullanıyorsanız geliştirici sunucunuzu yeniden başlattığınızdan emin olun.

Not: Linterınıza küresel hakkında bilgi vermeyi unutmayın, bu yüzden şikayet etmeyecektir. Örneğin, ESLint için cevabımı buraya bakın .

3) Webpack'in DefinePlugin'ini kullanın

Globalleriniz için dize değerleriyle const kullanmak istiyorsanız, bu eklentiyi Webpack eklentileri listenize ekleyebilirsiniz:

new webpack.DefinePlugin({
  PRODUCTION: JSON.stringify(true),
  VERSION: JSON.stringify("5fa3b9"),
  BROWSER_SUPPORTS_HTML5: true,
  TWO: "1+1",
  "typeof window": JSON.stringify("object")
})

Gibi kullanın:

console.log("Running App version " + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require("html5shiv");

4) Genel pencere nesnesini (veya Düğümün genelini) kullanın

window.foo = 'bar'  // For SPA's, browser environment.
global.foo = 'bar'  // Webpack will automatically convert this to window if your project is targeted for web (default), read more here: https://webpack.js.org/configuration/node/

Bunun çoklu dolgular için yaygın olarak kullanıldığını göreceksiniz, örneğin: window.Promise = Bluebird

5) dotenv gibi bir paket kullanın

(Sunucu tarafı projeleri için) dotenv paketi yerel bir yapılandırma dosyası alır (herhangi bir anahtar / kimlik bilgisi varsa .gitignore'nuza ekleyebilir) ve yapılandırma değişkenlerinizi Düğümün process.env nesnesine ekler .

// As early as possible in your application, require and configure dotenv.    
require('dotenv').config()

.envProjenizin kök dizininde bir dosya oluşturun . Şeklinde yeni satırlara ortama özgü değişkenler ekleyin NAME=VALUE. Örneğin:

DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3

Bu kadar.

process.envartık .envdosyanızda tanımladığınız anahtarlar ve değerler var .

var db = require('db')
db.connect({
  host: process.env.DB_HOST,
  username: process.env.DB_USER,
  password: process.env.DB_PASS
})

Notlar:

Webpack'in Harici Cihazları ile ilgili olarak , bazı modüllerin yerleşik paketinize dahil edilmesini engellemek istiyorsanız kullanın. Webpack modülü dünya çapında kullanılabilir hale getirecek, ancak paketinize koymayacaktır. Bu, sayfanızda zaten ayrı komut dosyası etiketlerinde (belki de bir CDN'den ) yüklü olduğu jQuery gibi büyük kütüphaneler için kullanışlıdır (çünkü dış paketleri sallayan Webpack'te çalışmaz ).


3
+1. Web paketini bir oluşturma aracı olarak kullanmak için bir uygulamayı yeniden yapılandırıyorum ve bu başlangıçta benim için işe yaramadı çünkü utilshedef dosyaya kendi ad alanımla ilgili herhangi bir referans eklemedim - başlangıçta sadece tarayıcının kesme noktasını koymuştum kaynak pencere ve neden utilstanımlanmadı üzerine şaşkın devam etti . Sonunda, web paketinin (oldukça akıllıca) sadece ad alanına en az bir kez atıfta bulunulursa bir modül içerdiğini keşfettim . Ben hedef dosyanın yarar fonksiyonlarının önsöz yapmışlar kez Dolayısıyla utils, modül edildi dahil.
nb1987

Evet, yalnızca kullandığınız yerde kullanılabilir hale getirir. Bunu cevabın ilk satırına koydum, ama hafif bir ayar yaptım, belki daha iyi okur. +1 için teşekkürler!
prograhammer

1
ProvidePlugin'in aslında modülleri yüklediğini ve sadece bir değişkene ihtiyacınız varsa, bu şekilde çalışmadığını unutmayın. externalsGlobal bir değişken oluşturmanız gerekiyorsa bunun yerine kullanın . Örnek: externals: { 'webpackVariables': `{ serverUrl: '${ env.server }', cordovaBuild: '${ env.cordova }', }`, }, Öyleyse kullanconst webpackVariables = require('webpackVariables');
Brian Haak

1
Ve bu yaklaşımı TypeScript ile nasıl kullanabilirim biliyor musunuz? Eğer bildirilmemiş bir değişken kullanırsanız bir hata atar ...
knaos

2
@prograhammer Aslında, çözümü zaten buldum. Senin genellikle uygulamanın kök, içinde tsconfig.json , sen bir tanım dosyasını adında eklemem gerekiyor global.d.ts . İçinde küresel değişkenleri şöyle bildirebilirsiniz: declare const isProduction: bool;Referans için, şunu kontrol edin typescriptlang.org/docs/handbook/declaration-files/templates/…
knaos

45

Ben de aynı soruyu sormak üzereydim. WebPack belgelerine kısmını biraz daha arama ve decyphering sonra ne istediğinizi olduğunu düşünüyorum output.libraryve output.libraryTargetde webpack.config.jsdosyaya.

Örneğin:

js / index.js:

var foo = 3;
var bar = true;

webpack.config.js

module.exports = {
   ...
   entry: './js/index.js',
   output: {
      path: './www/js/',
      filename: 'index.js',
      library: 'myLibrary',
      libraryTarget: 'var'
   ...
}

Artık oluşturulan www/js/index.jsdosyayı bir html komut dosyası etiketine bağlarsanız myLibrary.foo, diğer komut dosyalarınızın herhangi bir yerinden erişebilirsiniz .


3
Bu eksik olduğunu düşündüğünüz export { foo }gelen index.js?
LondonAppDev

myLibrary benim durumumda başka bir dosyada undefined veriyor. Lütfen bana yardım edebilir misin
RVCoder

17

DefinePlugin kullanın .

DefinePlugin, derleme zamanında yapılandırılabilen genel sabitler oluşturmanıza olanak tanır.

new webpack.DefinePlugin(definitions)

Misal:

plugins: [
  new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(true)
  })
  //...
]

Kullanımı:

console.log(`Environment is in production: ${PRODUCTION}`);

14

Define komutunu kullanabilirsiniz window.myvar = {}. Kullanmak istediğinizde,window.myvar = 1


EMCAScript 6. çalışmaz Bu ile hata üretir var window.CKEDITOR_BASEPATH = {};Hata sonra "Beklenmeyen Token" dırwindow.
Routhinator

1
Afedersiniz. Cevabımı yeni güncelledim. Sen gerektiğini varanahtar kelime. window.CKEDITOR_BASEPATH = {};
Anh Nguyen

Bu çalışır, maalesef sahip olduğum sorun, CKEditor'dan önce pakete yüklenmesine ihtiyacım var, ancak Webpack, benim ithalat / js'ime nereye koyarsam yerleştirir ısrar ediyor. : /
Routhinator

2

Genel değişkenleri en alakalı oldukları sınıflarda statik özellikler olarak ayarlayarak bu sorunu çözdüm. ES5'te şöyle görünür:

var Foo = function(){...};
Foo.globalVar = {};
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.