Passare variabili dipendenti dall’ambiente nel webpack

Sto provando a convertire un’app angular da gulp a webpack. in Gulp, utilizzo pre-gulp per sostituire alcune variabili nella pagina html (ad esempio il nome del database) a seconda di NODE_ENV. Qual è il modo migliore per ottenere un risultato simile con il webpack?

Ci sono due modi fondamentali per raggiungere questo objective.

DefinePlugin

new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') }), 

Si noti che questo sostituirà semplicemente le corrispondenze “così come sono”. Ecco perché la stringa è nel formato che è. Potresti avere una struttura più complessa, come un object, ma hai un’idea.

EnvironmentPlugin

 new webpack.EnvironmentPlugin(['NODE_ENV']) 

EnvironmentPlugin utilizza DefinePlugin internamente e mappa i valori dell’ambiente per codificarlo. Sintassi di Terser.

Alias

In alternativa è ansible utilizzare la configurazione tramite un modulo con alias . Dal lato del consumatore, assomiglierebbe a questo:

 var config = require('config'); 

La configurazione stessa potrebbe assomigliare a questa:

 resolve: { alias: { config: path.join(__dirname, 'config', process.env.NODE_ENV) } } 

Diciamo che process.env.NODE_ENV è lo development . ./config/development.js quindi essere ./config/development.js in ./config/development.js . Il modulo a cui è mappato può esportare la configurazione in questo modo:

 module.exports = { testing: 'something', ... }; 

Solo un’altra opzione, se si desidera utilizzare solo un’interfaccia cli, basta usare l’opzione define di webpack. Aggiungo il seguente script nel mio package.json :

 "build-production": "webpack -p --define process.env.NODE_ENV='\"production\"' --progress --colors" 

Quindi devo solo eseguire npm run build-production .

Ho esaminato un paio di opzioni su come impostare variabili specifiche per l’ambiente e ho finito con questo:

Attualmente ho 2 configurazioni di webpack:

webpack.production.config.js

 new webpack.DefinePlugin({ 'process.env':{ 'NODE_ENV': JSON.stringify('production'), 'API_URL': JSON.stringify('http://localhost:8080/bands') } }), 

webpack.config.js

 new webpack.DefinePlugin({ 'process.env':{ 'NODE_ENV': JSON.stringify('development'), 'API_URL': JSON.stringify('http://10.10.10.10:8080/bands') } }), 

Nel mio codice ottengo il valore di API_URL in questo modo (breve):

const apiUrl = process.env.API_URL;

EDIT 3 novembre 2016

I documenti Webpack hanno un esempio: https://webpack.js.org/plugins/define-plugin/#usage

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

Con ESLint è necessario consentire in modo specifico le variabili non definite nel codice, se non si dispone di no-undef regola no-undef . http://eslint.org/docs/rules/no-undef piace questo:

 /*global TWO*/ console.log('Running App version ' + TWO); 

EDIT 7 settembre 2017 (specifico per l’app Create-React)

Se non si sta configurando troppo, consultare Create-React-App: Create-React-App – Aggiunta di variabili d’ambiente personalizzate . Sotto il cofano CRA usa comunque Webpack.

È ansible utilizzare direttamente EnvironmentPlugin disponibile in webpack per accedere a qualsiasi variabile di ambiente durante la transpilation.

Devi solo dichiarare il plugin nel tuo file webpack.config.js :

 var webpack = require('webpack'); module.exports = { /* ... */ plugins = [ new webpack.EnvironmentPlugin(['NODE_ENV']) ] }; 

Si noti che è necessario dichiarare esplicitamente il nome delle variabili di ambiente che si desidera utilizzare.

Puoi passare qualsiasi argomento da riga di comando senza plugin aggiuntivi usando --env dal webpack 2:

 webpack --config webpack.config.js --env.foo=bar 

Utilizzando la variabile in webpack.config.js:

 module.exports = function(env) { if (env.foo === 'bar') { // do something } } 

fonte

Per aggiungere al mazzo di risposte personalmente preferisco il seguente:

 const webpack = require('webpack'); const prod = process.argv.indexOf('-p') !== -1; module.exports = { ... plugins: [ new webpack.DefinePlugin({ process: { env: { NODE_ENV: prod? `"production"`: '"development"' } } }), ... ] }; 

Usando questo non ci sono variabili env funky o problemi multipiattaforma (con env vars). Tutto ciò che fai è eseguire il normale webpack o webpack -p per dev o production.

Riferimento: problema Github

Dal momento che la mia modifica sul post di cui sopra il vangelista non è stata approvata , la pubblicazione di ulteriori informazioni.

Se si desidera prelevare valore da package.json come un numero di versione definito e accedervi tramite DefinePlugin all’interno di Javascript.

 {"version": "0.0.1"} 

Quindi, import package.json all’interno di rispettivo webpack.config , accedere all’attributo utilizzando la variabile di importazione, quindi utilizzare l’attributo in DefinePlugin .

 const PACKAGE = require('../package.json'); const _version = PACKAGE.version;//Picks the version number from package.json 

Ad esempio determinate configurazioni su webpack.config utilizzano METADATA per DefinePlugin:

 const METADATA = webpackMerge(commonConfig({env: ENV}).metadata, { host: HOST, port: PORT, ENV: ENV, HMR: HMR, RELEASE_VERSION:_version//Version attribute retrieved from package.json }); new DefinePlugin({ 'ENV': JSON.stringify(METADATA.ENV), 'HMR': METADATA.HMR, 'process.env': { 'ENV': JSON.stringify(METADATA.ENV), 'NODE_ENV': JSON.stringify(METADATA.ENV), 'HMR': METADATA.HMR, 'VERSION': JSON.stringify(METADATA.RELEASE_VERSION)//Setting it for the Scripts usage. } }), 

Accedi a questo in qualsiasi file typescript:

 this.versionNumber = process.env.VERSION; 

Il modo più intelligente sarebbe così:

 // webpack.config.js plugins: [ new webpack.DefinePlugin({ VERSION: JSON.stringify(require("./package.json").version) }) ] 

Grazie a Ross Allen

Solo un’altra risposta simile alla risposta di @ zer0chain. Tuttavia, con una distinzione.

L’impostazione di webpack -p è sufficiente.

È lo stesso di:

 --define process.env.NODE_ENV="production" 

E questo è lo stesso di

 // webpack.config.js const webpack = require('webpack'); module.exports = { //... plugins:[ new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }) ] }; 

Quindi potresti aver bisogno di qualcosa del genere nel file package.json Node:

 { "name": "projectname", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "debug": "webpack -d", "production": "webpack -p" }, "author": "prosti", "license": "ISC", "dependencies": { "webpack": "^2.2.1", ... } } 

Solo alcuni suggerimenti da DefinePlugin :

DefinePlugin consente di creare costanti globali che possono essere configurate in fase di compilazione. Questo può essere utile per consentire un comportamento diverso tra build di sviluppo e build di rilascio. Ad esempio, è ansible utilizzare una costante globale per determinare se la registrazione ha luogo; forse esegui il log nella tua build di sviluppo ma non nella build di rilascio. Questo è il tipo di scenario che DefinePlugin facilita.


In questo modo è ansible controllare se si digita webpack --help

 Config options: --config Path to the config file [string] [default: webpack.config.js or webpackfile.js] --env Enviroment passed to the config, when it is a function Basic options: --context The root directory for resolving entry point and stats [string] [default: The current directory] --entry The entry point [string] --watch, -w Watch the filesystem for changes [boolean] --debug Switch loaders to debug mode [boolean] --devtool Enable devtool for better debugging experience (Example: --devtool eval-cheap-module-source-map) [string] -d shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo [boolean] -p shortcut for --optimize-minimize --define process.env.NODE_ENV="production" [boolean] --progress Print compilation progress in percentage [boolean] 

Per aggiungere al gruppo di risposte:

Usa ExtendedDefinePlugin invece di DefinePlugin

 npm install extended-define-webpack-plugin --save-dev. 

ExtendedDefinePlugin è molto più semplice da usare ed è documentato 🙂 link

Perché DefinePlugin manca di buona documentazione, voglio dare una mano, dicendo che in realtà funziona come #DEFINE in C # .

 #if (DEBUG) Console.WriteLine("Debugging is enabled."); #endif 

Quindi, se vuoi capire come funziona DefinePlugin, leggi la doucmentation c # #define. collegamento

Ho trovato la seguente soluzione per essere più facile da configurare la variabile di ambiente per Webpack 2:

Ad esempio disponiamo di impostazioni webpack:

 var webpack = require('webpack') let webpackConfig = (env) => { // Passing envirmonment through // function is important here return { entry: { // entries }, output: { // outputs }, plugins: [ // plugins ], module: { // modules }, resolve: { // resolves } } }; module.exports = webpackConfig; 

Aggiungi variabile di ambiente in Webpack:

 plugins: [ new webpack.EnvironmentPlugin({ NODE_ENV: 'development', }), ] 

Definisci la variabile del plugin e aggiungila ai plugins :

  new webpack.DefinePlugin({ 'NODE_ENV': JSON.stringify(env.NODE_ENV || 'development') }), 

Ora, quando si esegue il comando webpack, passare env.NODE_ENV come argomento:

 webpack --env.NODE_ENV=development // OR webpack --env.NODE_ENV development 

Ora puoi accedere NODE_ENV variabile NODE_ENV ovunque nel tuo codice.

Preferisco usare il file .env per ambienti diversi.

  1. Utilizzare webpack.dev.config per copiare env.dev in .env nella cartella principale
  2. Usa webpack.prod.config per copiare env.prod in .env

e nel codice

uso

require('dotenv').config(); const API = process.env.API ## which will store the value from .env file

Ecco un modo che ha funzionato per me e mi ha permesso di mantenere le mie variabili di ambiente A SECCO riutilizzando un file json.

 let config = require('./settings.json'); if (__PROD__) { config = require('./settings-prod.json'); } const envVars = {}; Object.keys(config).forEach((key) => { envVars[key] = JSON.stringify(config[key]); }); new webpack.DefinePlugin({ 'process.env': envVars }), 

Non so perché, ma nessuno menziona davvero la soluzione più semplice. Questo funziona per me per nodejs e grunt. Come per molte persone il webpack può essere fonte di confusione, puoi semplicemente utilizzare la riga sottostante:

process.env.NODE_ENV = 'production';

Con la soluzione di cui sopra non hai davvero bisogno di usare envify o webpack. A volte la semplice soluzione hardcoded può funzionare per alcune persone.