我正在尝试将一个angular应用程序从gulp转换为webpack。在gulp中,我使用gulp预处理来替换html页面中的一些变量(例如数据库名称),这取决于NODE_ENV。用webpack实现类似结果的最佳方法是什么?


当前回答

我的webpack版本“webpack”:“^4.29.6”的变通方法非常简单。

//package.json
{
...
 "scripts": {
    "build": "webpack --mode production",
    "start": "webpack-dev-server --open --mode development"
  },
}

你可以在webpack命令中传递——mode参数,然后在webpack.config.js中

 // webpack.config.json
 module.exports = (env,argv) => {
        return {
           ...
           externals: {
            // global app config object
            config: JSON.stringify({
                apiUrl: (argv.mode==="production") ? '/api' : 'localhost:3002/api'
            })
        }
}

我在代码中像这样使用baseurl

// my api service
import config from 'config';
console.log(config.apiUrl) // like fetch(`${config.apiUrl}/users/user-login`)

其他回答

这是另一个类似于@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')
    })
  ]
};

所以你可能只需要打包这样的东西。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允许您创建可以在编译时配置的全局常量。这对于允许开发构建和发布构建之间的不同行为是有用的。例如,您可以使用一个全局常量来确定是否进行日志记录;也许您在开发构建中执行日志记录,但在发布构建中不执行。这就是DefinePlugin所促进的那种场景。


这样你就可以检查你是否输入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]

我研究了几个关于如何设置特定于环境的变量的选项,最后得到了这样的结果:

我目前有2个webpack配置:

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的值:

统一文件格式

编辑2016年11月3日

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")
})

使用ESLint,如果你有no-undef规则,你需要在代码中明确地允许未定义的变量。http://eslint.org/docs/rules/no-undef像这样:

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

EDIT 2017年9月7日(Create-React-App特定)

如果您不喜欢配置太多,请查看Create-React-App: Create-React-App -添加自定义环境变量。实际上CRA使用Webpack。

这里有一种方法,对我来说是有效的,并允许我通过重用json文件保持我的环境变量DRY。

const webpack = require('webpack');
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
}),

你可以直接使用webpack中的EnvironmentPlugin来在编译过程中访问任何环境变量。

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

var webpack = require('webpack');

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

注意,必须显式声明要使用的环境变量的名称。

dotenv-webpack

一个安全的webpack插件,支持dotenv和其他环境变量,只公开您选择和使用的内容。

通过一些基于默认选项的配置解决方案来实现这一点,一旦包有.env.defaults文件作为env变量的初始值,您就可以在开发中使用它,并让.env用于生产。

使用

安装包

npm install dotenv-webpack --save-dev

创建一个.env.defaults文件

API_URL='dev_url/api/'

创建一个.env文件,保留它为空,使用默认值,在部署过程中更新它 配置webpack - webpack. Config .js

new Dotenv({
  defaults: true 
})

开发环境测试文件。js

console.log(process.env.API_URL)
// Outputs: dev_url/api/

在构建时,更新空的.env文件

API_URL='prod_url/api/'

Dotenv-webpack将使用这个来覆盖env.defaults

产品环境测试文件。js

console.log(process.env.API_URL)
// Outputs: prod_url/api/

dotenv-webpack dotenv-defaults