我正在尝试将一个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。

其他回答

因为我在上面的帖子上的编辑没有被批准,所以发布了额外的信息。

如果你想从包装中挑选价值。类似于定义的版本号,并通过Javascript中的DefinePlugin访问它。

{"version": "0.0.1"}

然后,导入包。Json在各自的webpack中。config,使用import变量访问该属性,然后在DefinePlugin中使用该属性。

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

例如,webpack上的某些配置。config为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.
        }
      }),

在任何typescript文件中访问它:

this.versionNumber = process.env.VERSION;

最聪明的方法是这样的:

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

感谢罗斯·艾伦

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

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',
    ...
};

我发现下面的解决方案是最容易为Webpack 2设置环境变量:

例如,我们有一个webpack设置:

var webpack = require('webpack')

let webpackConfig = (env) => { // Passing envirmonment through
                                // function is important here
    return {
        entry: {
        // entries
        },

        output: {
        // outputs
        },

        plugins: [
        // plugins
        ],

        module: {
        // modules
        },

        resolve: {
        // resolves
        }

    }
};

module.exports = webpackConfig;

在Webpack中添加环境变量:

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

定义插件变量并将其添加到插件中:

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

现在当运行webpack命令时,传递env。NODE_ENV作为参数:

webpack --env.NODE_ENV=development

// OR

webpack --env.NODE_ENV development

现在您可以在代码中的任何地方访问NODE_ENV变量。

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

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

我的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`)