在webpack中传递依赖于环境的variables

我正在尝试将一个angular度的应用程序从吞噬转换为webpack。 在gulp中,我使用gulp-preprocess来取代html页面中的一些variables(例如数据库名称),这取决于NODE_ENV。 用webpack实现类似结果的最好方法是什么?

有两个基本的方法来实现这一点。

DefinePlugin

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

请注意,这将只是replace“原样”的匹配。 这就是为什么string是在它的格式。 你可以有一个更复杂的结构,比如那个对象,但是你明白了。

EnvironmentPlugin

 new webpack.EnvironmentPlugin(['NODE_ENV']) 

EnvironmentPlugin DefinePlugin内部使用DefinePlugin并通过它将环境值映射到代码。 Terser语法。

别号

或者,您可以通过别名模块使用configuration。 从消费者的angular度来看,这将是这样的:

 var config = require('config'); 

configuration本身可能是这样的:

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

比方说process.env.NODE_ENVdevelopment 。 它会映射到./config/development.js 。 它映射到的模块可以像这样导出configuration:

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

只是另一种select,如果您只想使用cli接口,只需使用webpack的define选项即可。 我在我的package.json添加下面的脚本:

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

所以我只需要运行npm run build-production

我调查了几个关于如何设置环境特定variables的选项,并以此结束:

我目前有2个webpackconfiguration:

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

在我的代码中,我以这个(简短的)方式获得了API_URL的值:

const apiUrl = process.env.API_URL;

编辑2016年11月3日

Webpack文档有一个例子: https ://webpack.github.io/docs/list-of-plugins.html#dependency-injection

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

有了ESLint ,如果你有no-undef规则,你需要特别的允许未定义的代码variables。 http://eslint.org/docs/rules/no-undef是这样的:;

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

编辑2017年9月7日(创build – 反应 – 特定应用程序)

如果你没有太多configuration,请查看Create-React-App: Create-React-App – 添加自定义环境variables 。 无论如何,CRA使用Webpack。

您可以直接使用webpack提供的EnvironmentPluginwebpack中访问任何环境variables。

你只需要在你的webpack.config.js文件中声明这个插件:

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

请注意,您必须明确声明要使用的环境variables的名称。

您可以在webpack 2中使用--env传递命令行参数:

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

在webpack.config.js中使用variables:

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

资源

为了增加一大堆的答案,我个人更喜欢以下内容:

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

使用这个没有时髦的envvariables或跨平台问题(envvariables)。 你所做的就是分别运行正常的webpackwebpack -p进行开发或生产。

参考: Github的问题

由于我在编辑上述职位的工作人员没有批准 ,发布额外的信息。

如果你想从package.json中select一个定义版本号的值,并通过Javascript中的DefinePlugin来访问它。

 {"version": "0.0.1"} 

然后,在相应的webpack.config中导入package.json ,使用importvariables访问该属性,然后使用DefinePlugin中的属性。

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

例如, webpack.config上的某些configuration使用了METADATA for 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. } }), 

在任何打字稿文件中访问:

 this.versionNumber = process.env.VERSION; 

最聪明的方式是这样的:

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

感谢Ross Allen

只是另一个类似@ zer0chain的答案的答案。 但是,有一个区别。

设置webpack -p就足够了。

这是一样的:

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

这是一样的

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

所以你可能只需要在package.json节点文件中需要这样的东西:

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

只是DefinePlugin的一些提示:

DefinePlugin允许您创build可在编译时configuration的全局常量。 这对于允许开发构build和发布构build之间的不同行为是有用的。 例如,您可以使用全局常量来确定是否进行日志logging; 也许你在开发版本中执行日志logging,但不是在发行版本中。 这是DefinePlugin所促成的那种场景。


这是这样,你可以检查你是否inputwebpack --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] 

要添加到一堆答案:

使用ExtendedDefinePlugin代替DefinePlugin

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

ExtendedDefinePlugin使用起来更简单,并logging在:-) 链接

由于DefinePlugin 缺乏良好的文档,我想通过说它实际上像C#中的#DEFINE一样工作。

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

因此,如果你想了解DefinePlugin是如何工作的,请阅读c##define doucmentation。 链接

我发现以下解决scheme最容易为Webpack 2设置环境variables:

比如我们有一个webpack设置:

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

在Webpack中添加环境variables:

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

定义插件variables并将其添加到plugins

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

现在,在运行webpack命令时,将env.NODE_ENV作为parameter passing:

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

现在你可以在代码的任何地方访问NODE_ENVvariables。

我更喜欢使用.env文件来适应不同的环境。

  1. 使用webpack.dev.config将env.dev复制到.env到根文件夹中
  2. 使用webpack.prod.config将env.prod复制到.env

并在代码中

使用

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

我不知道为什么,但没有人真正提到最简单的解决scheme。 这适用于nodejs和grunt。 至于许多人的webpack可能会令人困惑,你可以简单地使用下面的行:

process.env.NODE_ENV = 'production';

有了上述解决scheme,您并不需要使用envify或webpack。 有时候,简单的硬编码解决scheme可能适用于某些人。