Passer des variables dépendantes de l'environnement dans webpack

j'essaie de convertir une application angulaire de gulfp en webpack. dans gulfp j'utilise gulfp-preprocess pour remplacer certaines variables dans la page html (par exemple le nom de la base de données) en fonction du NODE_ENV. Quelle est la meilleure façon d'obtenir un résultat similaire avec webpack?

262
demandé sur Jeff Puckett 2015-05-04 15:20:14

13 réponses

il y a deux façons fondamentales d'y parvenir.

DefinePlugin

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

notez que ceci remplacera simplement les allumettes"telles quelles". C'est pourquoi la chaîne est dans le format qu'il est. Vous pourriez avoir une structure plus complexe, comme un objet, mais vous obtenez l'idée.

Environnementplugin

new webpack.EnvironmentPlugin(['NODE_ENV'])

EnvironmentPlugin utilise DefinePlugin à l'interne et cartographie les valeurs de l'environnement pour coder à travers elle. Syntaxe Terser.

Alias

alternativement vous pouvez consommer la configuration par un module aliasé . Du côté des consommateurs, il ressemblerait à ceci:

var config = require('config');

la Configuration elle-même pourrait ressembler à ceci:

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

disons process.env.NODE_ENV est development . Il se transformerait alors en ./config/development.js . Le module cartes de pouvez exporter configuration comme ceci:

module.exports = {
    testing: 'something',
    ...
};
384
répondu Juho Vepsäläinen 2016-12-23 07:08:12

juste une autre option, si vous voulez utiliser seulement une interface cli, utilisez simplement l'option define de webpack. J'ajoute le script suivant dans mon package.json :

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

donc je dois juste lancer npm run build-production .

102
répondu zer0chain 2016-03-24 14:06:27

j'ai étudié quelques options sur la façon de définir des variables spécifiques à l'environnement et j'ai fini avec ceci:

j'ai 2 configurations webpack actuellement:

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

dans mon code, J'obtiens la valeur de API_URL de cette manière (brève):

const apiUrl = process.env.API_URL;

EDIT 3 Nov, 2016

Webpack docs a un exemple: 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")
})

Avec ESLint vous devez autoriser expressément les variables non définies dans le code, si vous avez no-undef de la règle. http://eslint.org/docs/rules/no-undef comme ceci:

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

MODIFIER 7 Sep, 2017 (Créer-Réagir-Application spécifique)

si vous ne voulez pas configurer trop, consultez Créer-React-App: créer-React-App - Ajouter des Variables D'environnement personnalisées . Sous le capot, L'Arc utilise Webpack de toute façon.

62
répondu thevangelist 2018-07-12 13:23:00

vous pouvez utiliser directement le EnvironmentPlugin disponible dans webpack pour avoir accès à n'importe quelle variable d'environnement pendant la transpilation.

il vous suffit de déclarer le plugin dans votre fichier webpack.config.js :

var webpack = require('webpack');

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

Notez que vous devez déclarer explicitement le nom des variables d'environnement que vous souhaitez utiliser.

21
répondu Kuhess 2016-06-20 16:07:33

vous pouvez passer n'importe quel argument de ligne de commande sans plugins supplémentaires en utilisant --env depuis webpack 2:

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

en utilisant la variable dans webpack.config.js:

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

Source

20
répondu andruso 2018-06-13 12:47:15

ajouter au tas de réponses personnellement, je préfère le suivant:

const webpack = require('webpack');
const prod = process.argv.indexOf('-p') !== -1;

module.exports = {
  ...
  plugins: [
    new webpack.DefinePlugin({
      process: {
        env: {
          NODE_ENV: prod? `"production"`: '"development"'
        }
      }
    }),
    ...
  ]
};

en utilisant ceci, il n'y a pas de problèmes funky de variables env ou de plateforme croisée (avec les var env). Tout ce que vous faites est d'exécuter la normale webpack ou webpack -p pour dev ou la production respectivement.

la Référence: Github question

12
répondu Goblinlord 2016-10-27 00:36:10

depuis mon édition sur le ci-dessus post par le vangelist n'a pas été approuvé , en affichant des informations supplémentaires.

si vous voulez choisir la valeur du paquet .json comme défini un numéro de version et y accéder par DefinePlugin à l'intérieur de Javascript.

{"version": "0.0.1"}

Puis, Importer paquet.json à l'intérieur webpack.config , accédez à l'attribut en utilisant la variable d'importation, puis utilisez l'attribut dans le DefinePlugin .

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

par exemple certaines configurations sur webpack.config utilise des métadonnées pour 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.
        }
      }),

accéder à l'intérieur de n'importe quel fichier dactylographié:

this.versionNumber = process.env.VERSION;

la manière la plus intelligente serait comme ceci:

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

merci à Ross Allen

12
répondu Abhijeet 2017-05-23 11:47:32

juste une autre réponse qui est similaire à la réponse de @zer0chain. Cependant, avec une distinction.

le réglage webpack -p est suffisant.

C'est la même chose que:

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

Et c'est la même chose que

// webpack.config.js
const webpack = require('webpack');

module.exports = {
  //...

  plugins:[
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    })
  ]
};

donc vous pouvez n'avoir besoin de quelque chose comme ça que dans package.json fichier de Noeud:

{
  "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",
    ...
  }
}

quelques conseils de la DefinePlugin :

la DefinePlugin vous permet de créer des constantes globales qui peuvent être configurées au moment de la compilation. Cela peut être utile pour permettre des comportements différents entre les constructions de développement et les constructions de publication. Par exemple, vous pouvez utiliser une constante globale pour déterminer si la journalisation a lieu; peut-être effectuez-vous la journalisation dans votre construction de développement mais pas dans la construction de version. C'est le genre de scénario le DefinePlugin faciliter.


que vous pouvez vérifier si vous tapez 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]
11
répondu prosti 2017-02-09 00:15:37

ajouter au tas de réponses:

Utiliser ExtendedDefinePlugin au lieu de DefinePlugin

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

ExtendedDefinePlugin est beaucoup plus simple à utiliser et est documenté :-) lien

parce que DefinePlugin manque bonne documentation, je veux aider, en disant que cela fonctionne réellement comme #DEFINE in c# .

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

ainsi, si vous voulez comprendre comment fonctionne DefinePlugin, lisez le c# #define doucmentation. lien

3
répondu hannes neukermans 2016-11-22 15:36:39

j'ai trouvé la solution suivante pour être la plus facile à configurer la variable d'environnement pour Webpack 2:

par exemple, nous avons les paramètres 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;

ajouter Variable D'environnement dans Webpack:

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

définir la Variable Plugin et l'ajouter à plugins :

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

maintenant lors de l'exécution de la commande webpack, passer env.NODE_ENV comme argument:

webpack --env.NODE_ENV=development

// OR

webpack --env.NODE_ENV development

Now vous pouvez accéder à la variable NODE_ENV n'importe où dans votre code.

2
répondu ruddra 2018-06-15 07:31:01

je préfère utiliser .fichier de configuration pour les différents environnement.

  1. utilisez webpack.dev.config à la copie env.dev .env dans le dossier racine
  2. utilisez webpack.prod.config à la copie env.prod .env

et dans le code

utiliser

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

1
répondu Siva Kandaraj 2016-11-06 11:28:12

Voici une façon qui a fonctionné pour moi et qui m'a permis de garder mes variables d'environnement sèches en réutilisant un fichier 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
}),
0
répondu cbaigorri 2018-01-19 15:03:37

Je ne sais pas pourquoi mais personne ne mentionne vraiment la solution la plus simple. Ça marche pour moi pour nodejs et grunt. Comme pour beaucoup de gens, le webpack peut être déroutant, vous pouvez simplement utiliser la ligne suivante:

process.env.NODE_ENV = 'production';

Avec la solution ci-dessus, vous n'avez pas vraiment besoin d'utiliser envify ou webpack. Parfois, la solution simple et codée en dur peut fonctionner pour certaines personnes.

-4
répondu John Skoumbourdis 2016-10-06 17:26:18