webentwicklung-frage-antwort-db.com.de

Definiere globale Variable mit Webpack

Ist es möglich, eine globale Variable mit Webpack zu definieren, um etwa Folgendes zu erreichen:

var myvar = {};

Bei allen Beispielen, die ich gesehen habe, wurde die externe Datei require("imports?$=jquery!./file.js") verwendet.

93
Teneff

Es gibt verschiedene Möglichkeiten, sich Globalen zu nähern:

1) Fügen Sie Ihre Variablen in ein Modul ein.

Webpack wertet Module nur einmal aus, sodass Ihre Instanz global bleibt und Änderungen von Modul zu Modul durchläuft. Wenn Sie also so etwas wie einen globals.js und exportiere ein Objekt all deiner Globals, dann kannst du import './globals' und in diese Globals lesen/schreiben. Sie können in ein Modul importieren, Änderungen an dem Objekt aus einer Funktion vornehmen und in ein anderes Modul importieren und diese Änderungen in einer Funktion lesen. Denken Sie auch an die Reihenfolge, in der die Dinge geschehen. Das Webpack übernimmt zunächst alle Importe und lädt sie in der Reihenfolge, in der sie in Ihrem entry.js Beginnen. Dann wird entry.js Ausgeführt. Es ist also wichtig, wo Sie in Globals lesen/schreiben. Kommt es aus dem Stammbereich eines Moduls oder aus einer später aufgerufenen Funktion?

Hinweis: Wenn die Instanz jedes Mal new sein soll, verwenden Sie eine ES6-Klasse . Traditionell würden Sie in JS Klassen großschreiben (im Gegensatz zu Kleinbuchstaben für Objekte)
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()

2) Webpacks ProvidePlugin

Gehen Sie wie folgt vor, um das ProvidePlugin von Webpack zu verwenden (das ein Modul als Variable in jedem Modul und nur in den Modulen zur Verfügung stellt, in denen Sie es tatsächlich verwenden). Dies ist nützlich, wenn Sie nicht immer wieder import Bar from 'foo' Eingeben möchten. Oder Sie können hier ein Paket wie jQuery oder lodash als global einbinden (auch wenn Sie sich vielleicht Webpacks Externals ansehen).

Schritt 1) ​​Erstellen Sie ein beliebiges Modul. Zum Beispiel wäre ein globaler Satz von Dienstprogrammen praktisch:

utils.js

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

Schritt 2) Alias ​​des Moduls und zu ProvidePlugin hinzufügen:

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'
    })
  ]  

}

Rufen Sie jetzt einfach utils.sayHello() in einer beliebigen js-Datei auf und es sollte funktionieren. Stellen Sie sicher, dass Sie Ihren Dev-Server neu starten, wenn Sie das mit Webpack verwenden.

Hinweis: Vergiss nicht, deinem Linter etwas über das Globale zu erzählen, damit er sich nicht beschwert. Siehe zum Beispiel mein Antwort für ESLint hier .

3) Verwenden Sie Webpacks DefinePlugin

Wenn Sie const nur mit Zeichenfolgenwerten für Ihre globalen Elemente verwenden möchten, können Sie dieses Plugin zu Ihrer Liste der Webpack-Plugins hinzufügen:

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

Verwenden Sie es wie folgt:

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

4) Verwenden Sie das globale Fensterobjekt (oder das globale des Knotens)

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/

Dies wird häufig für Polyfills verwendet, zum Beispiel: window.Promise = Bluebird

5) Verwenden Sie ein Paket wie dotenv

(Für serverseitige Projekte) Das dotenv-Paket verwendet eine lokale Konfigurationsdatei (die Sie Ihrem .gitignore hinzufügen können, wenn Schlüssel/Anmeldeinformationen vorhanden sind) und fügt Ihre Konfigurationsvariablen dem process.env -Objekt des Knotens hinzu .

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

Erstellen Sie eine .env - Datei im Stammverzeichnis Ihres Projekts. Fügen Sie umgebungsspezifische Variablen in neuen Zeilen in Form von NAME=VALUE Hinzu. Zum Beispiel:

DB_Host=localhost
DB_USER=root
DB_PASS=s1mpl3

Das ist es.

process.env Enthält jetzt die Schlüssel und Werte, die Sie in Ihrer .env - Datei definiert haben.

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

Anmerkungen:

Verwenden Sie Webpacks Externals , wenn Sie einige Module von der Aufnahme in Ihr erstelltes Bundle ausschließen möchten. Webpack stellt das Modul global zur Verfügung, nimmt es jedoch nicht in Ihr Bundle auf. Dies ist praktisch für große Bibliotheken wie jQuery (da Tree Shaking für externe Pakete funktioniert in Webpack nicht ), bei denen Sie diese bereits in separaten Skript-Tags (möglicherweise von einem CDN) auf Ihrer Seite geladen haben.

217
prograhammer

Ich wollte gerade dieselbe Frage stellen. Nach etwas weiterem Suchen und Entschlüsseln eines Teils der Dokumentation von webpack denke ich, dass Sie den output.library und output.libraryTarget in der webpack.config.js-Datei wünschen.

Zum Beispiel:

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'
   ...
}

Wenn Sie nun die generierte www/js/index.js-Datei in einem HTML-Skript-Tag verknüpfen, können Sie von überall in Ihren anderen Skripts auf myLibrary.foo zugreifen.

33
OriolBG

Verwenden Sie DefinePlugin .

Mit dem DefinePlugin können Sie globale Konstanten erstellen, die .__ sein können. zur Kompilierzeit konfiguriert.

new webpack.DefinePlugin(definitions)

Beispiel:

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

Verwendungszweck:

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

Sie können define window.myvar = {}..__ verwenden. Wenn Sie es verwenden möchten, können Sie wie window.myvar = 1 verwenden.

8
Anh Nguyen

Ich habe dieses Problem gelöst, indem Sie die globalen Variablen als statische Eigenschaften für die Klassen festgelegt haben, für die sie am relevantesten sind. In ES5 sieht es so aus:

var Foo = function(){...};
Foo.globalVar = {};
0
pasx