Odpowiedzi:
Istnieje kilka sposobów podejścia do globalnych:
Webpack ocenia moduły tylko raz, więc Twoja instancja pozostaje globalna i przenosi zmiany z modułu na moduł. Więc jeśli utworzysz coś takiego jak a globals.js
i wyeksportujesz obiekt ze wszystkich swoich globalnych, możesz import './globals'
i czytać / zapisywać w tych globalnych. Możesz importować do jednego modułu, wprowadzać zmiany w obiekcie z funkcji i importować do innego modułu i odczytywać te zmiany w funkcji. Pamiętaj również o kolejności rzeczy. Webpack najpierw pobierze wszystkie importy i załaduje je, aby rozpocząć w Twoim entry.js
. Wtedy to się wykona entry.js
. Dlatego ważne jest, gdzie czytasz / piszesz do globali. Czy pochodzi z głównego zakresu modułu, czy z funkcji wywoływanej później?
Uwaga : jeśli chcesz, aby instancja występowała za new
każdym razem, użyj klasy ES6 . Tradycyjnie w JS można zapisywać klasy z wielkich liter (w przeciwieństwie do małych liter w przypadku obiektów), jak
import FooBar from './foo-bar' // <-- Usage: myFooBar = new FooBar()
Oto, jak możesz to zrobić za pomocą ProvidePlugin Webpacka (który udostępnia moduł jako zmienną w każdym module i tylko w tych modułach, w których faktycznie go używasz). Jest to przydatne, gdy nie chcesz ciągle pisać import Bar from 'foo'
. Możesz też przynieść pakiet taki jak jQuery lub lodash jako globalny tutaj (chociaż możesz rzucić okiem na zewnętrzne elementy Webpack ).
Krok 1) Utwórz dowolny moduł. Na przykład przydałby się globalny zestaw narzędzi:
utils.js
export function sayHello () {
console.log('hello')
}
Krok 2) Utwórz alias moduł i dodaj do ProvidePlugin:
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'
})
]
}
Teraz po prostu wywołaj utils.sayHello()
dowolny plik js i powinno działać. Upewnij się, że zrestartowałeś swój dev-server, jeśli używasz go z Webpack.
Uwaga: nie zapomnij powiedzieć linterowi o globalnym, aby nie narzekał. Na przykład zobacz moją odpowiedź dla ESLint tutaj .
Jeśli chcesz po prostu użyć const z wartościami ciągów dla twoich globali, możesz dodać tę wtyczkę do swojej listy wtyczek Webpack:
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
VERSION: JSON.stringify("5fa3b9"),
BROWSER_SUPPORTS_HTML5: true,
TWO: "1+1",
"typeof window": JSON.stringify("object")
})
Używaj go jak:
console.log("Running App version " + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require("html5shiv");
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/
Zobaczysz to często używane w przypadku wypełniaczy, na przykład: window.Promise = Bluebird
(Dla projektów po stronie serwera) Pakiet dotenv weźmie lokalny plik konfiguracyjny (który możesz dodać do swojego .gitignore, jeśli są jakieś klucze / poświadczenia) i doda twoje zmienne konfiguracyjne do obiektu process.env Node .
// As early as possible in your application, require and configure dotenv.
require('dotenv').config()
Utwórz .env
plik w katalogu głównym projektu. Dodaj zmienne specyficzne dla środowiska w nowych wierszach w postaci NAME=VALUE
. Na przykład:
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
Otóż to.
process.env
ma teraz klucze i wartości zdefiniowane w .env
pliku.
var db = require('db')
db.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS
})
Jeśli chodzi o zewnętrzne elementy Webpacka , użyj go, jeśli chcesz wykluczyć niektóre moduły z wbudowanego pakietu. Webpack sprawi, że moduł będzie dostępny globalnie, ale nie umieści go w pakiecie. Jest to przydatne dla dużych bibliotek, takich jak jQuery (ponieważ zewnętrzne pakiety wstrząsające drzewem nie działają w Webpack ), w których masz je już załadowane na swojej stronie w osobnych tagach skryptów (być może z CDN).
externals
zamiast tego, jeśli chcesz utworzyć zmienną globalną. Przykład: externals: { 'webpackVariables': `{ serverUrl: '${ env.server }', cordovaBuild: '${ env.cordova }', }`, },
użyj go jakoconst webpackVariables = require('webpackVariables');
declare const isProduction: bool;
Dla porównania, to sprawdzić typescriptlang.org/docs/handbook/declaration-files/templates/...
Właśnie miałem zadać to samo pytanie. Po dalszych poszukiwaniach i rozszyfrowaniu części dokumentacji webpacka myślę, że to czego potrzebujesz to output.library
i output.libraryTarget
w webpack.config.js
pliku.
Na przykład:
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'
...
}
Teraz, jeśli połączysz wygenerowany www/js/index.js
plik w tagu skryptu html, do którego możesz uzyskać dostęp myLibrary.foo
z dowolnego miejsca w innych skryptach.
export { foo }
z index.js
?
Użyj DefinePlugin .
DefinePlugin umożliwia tworzenie stałych globalnych, które można konfigurować w czasie kompilacji.
new webpack.DefinePlugin(definitions)
plugins: [
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true)
})
//...
]
console.log(`Environment is in production: ${PRODUCTION}`);
Możesz użyć funkcji define window.myvar = {}
. Jeśli chcesz go użyć, możesz użyć likewindow.myvar = 1
var window.CKEDITOR_BASEPATH = {};
błędem „Nieoczekiwany token” powindow.
var
słowo kluczowe. window.CKEDITOR_BASEPATH = {};
utils
przestrzeni nazw w pliku docelowym - początkowo po prostu wstawiłem punkt przerwania w przeglądarce okno źródłowe i ciągle zastanawiałem się, dlaczegoutils
nie zostało zdefiniowane. Wreszcie odkryłem, że WebPACK (raczej elegancko) tylko zawiera moduł jeśli jego nazw odwołuje się co najmniej raz. Dlatego też, gdy poprzedziłem jedną z funkcji narzędziowych pliku docelowegoutils
, moduł został dołączony.