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


当前回答

就我个人而言,我更喜欢以下这些答案:

const webpack = require('webpack');
const prod = process.argv.indexOf('-p') !== -1;

module.exports = {
  ...
  plugins: [
    new webpack.DefinePlugin({
      process: {
        env: {
          NODE_ENV: prod? `"production"`: '"development"'
        }
      }
    }),
    ...
  ]
};

使用它不会有奇怪的env变量或跨平台问题(使用env变量)。你所要做的就是分别为开发或生产运行普通的webpack或webpack -p。

参考:Github问题

其他回答

现在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种方法只是基本的,我相信还有更多的方法。但我认为这是最简单的方法。

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

如果你想从包装中挑选价值。类似于定义的版本号,并通过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)
    })
  ]

感谢罗斯·艾伦

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

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

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

你可以使用——env传递环境变量,而不需要额外的插件

Webpack -

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

Webpack 5+(无)

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

然后,使用webpack.config.js中的变量:

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

进一步阅读:Webpack 2.0不支持自定义命令行参数? # 2254

再给这些问题补充一个答案:

使用ExtendedDefinePlugin而不是DefinePlugin

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

ExtendedDefinePlugin使用起来更简单,并且有文档:-) 链接

因为DefinePlugin缺乏良好的文档,我想通过说它实际上像c#中的#DEFINE一样工作来帮助解决问题。

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

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