在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_ENV
是development
。 它会映射到./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
提供的EnvironmentPlugin
在webpack
中访问任何环境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)。 你所做的就是分别运行正常的webpack
或webpack -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_ENV
variables。
我更喜欢使用.env文件来适应不同的环境。
- 使用webpack.dev.config将
env.dev
复制到.env到根文件夹中 - 使用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可能适用于某些人。