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?
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',
...
};
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
.
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.
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.
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
}
}
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
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)
})
]
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]
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
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.
je préfère utiliser .fichier de configuration pour les différents environnement.
- utilisez webpack.dev.config à la copie
env.dev
.env dans le dossier racine - 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
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
}),
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.