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


当前回答

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

我目前有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。

其他回答

有两种基本方法可以实现这一点。

DefinePlugin

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

注意,这将只是替换匹配的“原样”。这就是为什么字符串是这样的格式。你可以有一个更复杂的结构,比如一个物体但你懂的。

EnvironmentPlugin

new webpack.EnvironmentPlugin(['NODE_ENV'])

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

别名

或者,您可以通过别名模块使用配置。从消费者的角度来看,它是这样的:

var config = require('config');

配置本身可能是这样的:

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

我们写入process。env。NODE_ENV是开发。然后它会映射到。/config/development.js。它映射到的模块可以像这样导出配置:

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

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

只是另一个选项,如果你只想使用cli界面,只需使用webpack的define选项。我在包中添加了以下脚本。json:

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

我只需要运行npm运行build-production。

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

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

var webpack = require('webpack');

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

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

现在2020年,我也面临着同样的问题,但是对于这个老问题,有很多新的答案,就列举一些吧:

这是webpack.config.js

plugins: [
        new HtmlWebpackPlugin({
            // 1. title is the parameter, you can use in ejs template
            templateParameters:{
                title: JSON.stringify(someting: 'something'),
            },
        }), 


        //2. BUILT_AT is a parameter too. can use it.
        new webpack.DefinePlugin({
            BUILT_AT: webpack.DefinePlugin.runtimeValue(Date.now,"some"),

        }),

        //3. for webpack5, you can use global variable: __webpack_hash__
        //new webpack.ExtendedAPIPlugin()
    ],
    //4. this is not variable, this is module, so use 'import tt' to use it.
    externals: { 
        'ex_title': JSON.stringify({
            tt: 'eitentitle',
        })
    },

这4种方法只是基本的,我相信还有更多的方法。但我认为这是最简单的方法。