Javascript 在 webpack 中传递依赖于环境的变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30030031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing environment-dependent variables in webpack
提问by kpg
I'm trying to convert an angular app from gulp to webpack. in gulp I use gulp-preprocess to replace some variables in the html page (e.g. database name) depending on the NODE_ENV. What is the best way of achieving a similar result with webpack?
我正在尝试将 angular 应用程序从 gulp 转换为 webpack。在 gulp 中,我使用 gulp-preprocess 根据 NODE_ENV 替换 html 页面中的一些变量(例如数据库名称)。使用 webpack 实现类似结果的最佳方法是什么?
回答by Juho Veps?l?inen
There are two basic ways to achieve this.
有两种基本方法可以实现这一点。
DefinePlugin
定义插件
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
}),
Note that this will just replace the matches "as is". That's why the string is in the format it is. You could have a more complex structure, such as an object there but you get the idea.
请注意,这只会“按原样”替换匹配项。这就是字符串采用其格式的原因。你可以有一个更复杂的结构,比如一个对象,但你明白了。
EnvironmentPlugin
环境插件
new webpack.EnvironmentPlugin(['NODE_ENV'])
EnvironmentPluginuses DefinePlugininternally and maps the environment values to code through it. Terser syntax.
EnvironmentPlugin在DefinePlugin内部使用并通过它将环境值映射到代码。更简洁的语法。
Alias
别名
Alternatively you could consume configuration through an aliased module. From consumer side it would look like this:
或者,您可以通过别名模块使用配置。从消费者方面来看,它看起来像这样:
var config = require('config');
Configuration itself could look like this:
配置本身可能如下所示:
resolve: {
alias: {
config: path.join(__dirname, 'config', process.env.NODE_ENV)
}
}
Let's say process.env.NODE_ENVis development. It would map into ./config/development.jsthen. The module it maps to can export configuration like this:
让我们说process.env.NODE_ENV是development。它会映射到./config/development.js那时。它映射到的模块可以像这样导出配置:
module.exports = {
testing: 'something',
...
};
回答by zer0chain
Just another option, if you want to use only a cli interface, just use the defineoption of webpack. I add the following script in my package.json:
只是另一种选择,如果您只想使用 cli 界面,只需使用definewebpack的选项。我在我的中添加以下脚本package.json:
"build-production": "webpack -p --define process.env.NODE_ENV='\"production\"' --progress --colors"
So I just have to run npm run build-production.
所以我只需要跑npm run build-production。
回答by thevangelist
I investigated a couple of options on how to set environment-specific variables and ended up with this:
我研究了几个关于如何设置特定于环境的变量的选项,最后得到了这个:
I have 2 webpack configs currently:
我目前有 2 个 webpack 配置:
webpack.production.config.js
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
webpack.config.js
new webpack.DefinePlugin({
'process.env':{
'NODE_ENV': JSON.stringify('development'),
'API_URL': JSON.stringify('http://10.10.10.10:8080/bands')
}
}),
In my code I get the value of API_URL in this (brief) way:
在我的代码中,我以这种(简短的)方式获取 API_URL 的值:
const apiUrl = process.env.API_URL;
const apiUrl = process.env.API_URL;
EDIT 3rd of Nov, 2016
编辑 2016 年 11 月 3 日
Webpack docs has an example: https://webpack.js.org/plugins/define-plugin/#usage
Webpack 文档有一个例子: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")
})
With ESLintyou need to specifically allow undefined variables in code, if you have no-undefrule on. http://eslint.org/docs/rules/no-undeflike this:
使用ESLint,如果您有no-undef规则,您需要在代码中明确允许未定义的变量。http://eslint.org/docs/rules/no-undef像这样:
/*global TWO*/
console.log('Running App version ' + TWO);
EDIT 7th of Sep, 2017 (Create-React-App specific)
编辑 2017 年 9 月 7 日(特定于 Create-React-App)
If you're not into configuring too much, check out Create-React-App: Create-React-App - Adding Custom Environment Variables. Under the hood CRA uses Webpack anyway.
如果您不想配置太多,请查看 Create-React-App:Create-React-App - 添加自定义环境变量。在幕后,CRA 无论如何都使用 Webpack。
回答by andruso
You can pass anycommand-line argument without additional pluginsusing --envsince webpack 2:
你可以通过任何命令行参数,无需额外的插件使用--env以来的WebPack 2:
webpack --config webpack.config.js --env.foo=bar
Using the variable in webpack.config.js:
使用 webpack.config.js 中的变量:
module.exports = function(env) {
if (env.foo === 'bar') {
// do something
}
}
回答by Kuhess
You can directly use the EnvironmentPluginavailable in webpackto have access to any environment variable during the transpilation.
在转译过程中,您可以直接使用EnvironmentPluginavailable inwebpack来访问任何环境变量。
You just have to declare the plugin in your webpack.config.jsfile:
你只需要在你的webpack.config.js文件中声明插件:
var webpack = require('webpack');
module.exports = {
/* ... */
plugins = [
new webpack.EnvironmentPlugin(['NODE_ENV'])
]
};
Note that you must declare explicitly the name of the environment variables you want to use.
请注意,您必须明确声明要使用的环境变量的名称。
回答by Goblinlord
To add to the bunch of answers personally I prefer the following:
为了个人添加到一堆答案中,我更喜欢以下内容:
const webpack = require('webpack');
const prod = process.argv.indexOf('-p') !== -1;
module.exports = {
...
plugins: [
new webpack.DefinePlugin({
process: {
env: {
NODE_ENV: prod? `"production"`: '"development"'
}
}
}),
...
]
};
Using this there is no funky env variable or cross-platform problems (with env vars). All you do is run the normal webpackor webpack -pfor dev or production respectively.
使用它没有时髦的环境变量或跨平台问题(使用环境变量)。您所做的就是分别运行正常webpack或webpack -p开发或生产。
Reference: Github issue
参考:Github 问题
回答by Abhijeet
Since my Edit on the above post by thevangelistwasn't approved, posting additional information.
由于我对上述帖子的编辑未获批准,因此发布了其他信息。
If you want to pick value from package.jsonlike a defined version numberand access it through DefinePlugininside Javascript.
如果你想从package.json 中选择一个像定义的版本号一样的值,并通过Javascript 中的DefinePlugin访问它。
{"version": "0.0.1"}
Then, Import package.jsoninside respective webpack.config, access the attribute using the import variable, then use the attribute in the DefinePlugin.
然后,在各自的webpack.config 中导入package.json,使用 import 变量访问该属性,然后在DefinePlugin 中使用该属性。
const PACKAGE = require('../package.json');
const _version = PACKAGE.version;//Picks the version number from package.json
For example certain configuration on webpack.configis using METADATA for DefinePlugin:
例如webpack.config上的某些配置使用 METADATA 作为 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.
}
}),
Access this inside any typescript file:
在任何打字稿文件中访问它:
this.versionNumber = process.env.VERSION;
The smartest way would be like this:
最聪明的方法是这样的:
// webpack.config.js
plugins: [
new webpack.DefinePlugin({
VERSION: JSON.stringify(require("./package.json").version)
})
]
回答by prosti
Just another answer that is similar to @zer0chain's answer. However, with one distinction.
另一个类似于@zer0chain 的答案的答案。但是,有一个区别。
Setting webpack -pis sufficient.
设置webpack -p就足够了。
It is the same as:
它与以下内容相同:
--define process.env.NODE_ENV="production"
And this is the same as
这与
// webpack.config.js
const webpack = require('webpack');
module.exports = {
//...
plugins:[
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
};
So you may only need something like this in package.jsonNode file:
所以你可能只需要在package.jsonNode 文件中这样的东西:
{
"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",
...
}
}
Just a few tips from the DefinePlugin:
来自DefinePlugin的一些提示:
The DefinePlugin allows you to create global constants which can be configured at compile time. This can be useful for allowing different behavior between development builds and release builds. For example, you might use a global constant to determine whether logging takes place; perhaps you perform logging in your development build but not in the release build. That's the sort of scenario the DefinePlugin facilitates.
DefinePlugin 允许您创建可以在编译时配置的全局常量。这对于允许开发版本和发布版本之间的不同行为很有用。例如,您可以使用全局常量来确定是否进行日志记录;也许您在开发版本中执行日志记录,但不在发布版本中执行。这就是 DefinePlugin 促进的场景。
That this is so you can check if you type webpack --help
这样你就可以检查你是否输入 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]
回答by hannes neukermans
To add to the bunch of answers:
添加到一堆答案中:
Use ExtendedDefinePlugininstead of DefinePlugin
使用ExtendedDefinePlugin而不是 DefinePlugin
npm install extended-define-webpack-plugin --save-dev.
ExtendedDefinePlugin is much simpler to use and is documented :-) link
ExtendedDefinePlugin 使用起来要简单得多,并且有文档记录:-) 链接
Because DefinePlugin lacksgood documentation, I want to help out, by saying that it actually works like #DEFINE in c#.
因为 DefinePlugin缺乏好的文档,我想提供帮助,说它实际上像c# 中的 #DEFINE一样工作。
#if (DEBUG)
Console.WriteLine("Debugging is enabled.");
#endif
Thus, if you want to understand how DefinePlugin works, read the c# #define doucmentation. link
因此,如果您想了解 DefinePlugin 的工作原理,请阅读 c# #define 文档。关联
回答by Siva Kandaraj
I prefer using .env file for different environment.
我更喜欢将 .env 文件用于不同的环境。
- Use webpack.dev.config to copy
env.devto .env into root folder - Use webpack.prod.config to copy
env.prodto .env
- 使用 webpack.dev.config 复制
env.dev到 .env 到根文件夹 - 使用 webpack.prod.config 复制
env.prod到 .env
and in code
并在代码中
use
用
require('dotenv').config();
const API = process.env.API ## which will store the value from .env file
require('dotenv').config();
const API = process.env.API ## which will store the value from .env file

