logo

鱼肚的博客

Don't Repeat Yourself

Webpack中设置banner信息

基本用法

在webpack输出的js中添加banner信息,尤其是一些版本信息,有时是能够辅助调试问题的。

本来设置banner是很简单的,webpack官方有文档:

1const webpack = require('webpack');
2
3new webpack.BannerPlugin('your banner info');
4// or
5new webpack.BannerPlugin(options);

它实现的效果,是在JS、LICENSE等文件的头部,添加给定的banner信息,默认用注释包裹起来。

在development中这个功能很正常,但是在production模式中,按照默认配置,terser/uglify会删除所有的注释,这就会出现冲突了。

而因为BannerPlugin不仅能插入注释,还能够插入祼代码(通过打开raw选项),所以也不能修改BannerPlugin的插入时机。

解决冲突

要解决terser/uglifyjs与banner之间的这个冲突,有多种方式。我这里介绍两种:

  1. 使BannerPlugin注入祼代码而不是注释
  2. 使terser/uglifyjs也输出banner信息

BannerPlugin输出祼代码

这个思路比较简单,但是对代码有侵入性。

既然 terser/uglifyjs 会删除注释,那就让banner信息不再是注释。

即打开BannerPlugin的raw选项,同时往里面插入一段不影响功能的代码,如在Window下挂载一个特殊的变量,使变量的值为banner信息。

这样一来,Banner注释变成了有用的代码,就不会被删除掉了。

Terser/Uglifyjs输出Banner信息

可以认为terser/uglifyjs也具备BannerPlugin的作用,但是用起来不如BannerPlugin方便。

后面以terser举例,说明具体用法。

terser中提供了preamble选项,关于它的介绍如下:

Preamble to prepend to the output. You can use this to insert a comment, for example for licensing information. This will not be parsed, but the source map will adjust for its presence.

要使用这种模式,首先将默认的minimize关闭:

1optimization: {
2  minimize: false
3}

然后引入terser-webpack-plugin:

1const TerserWebpackPlugin = require('terser-webpack-plugin');

最后在plugins中添加TerserWebpackPlugin,并设置对应的选项:

1new TerserWebpackPlugin({
2  cache: true,
3  parallel: true,
4  sourceMap: true,
5  terserOptions: {
6    output: {
7      preamble: '// your banner info' // 注意这里应该手动注释banner
8    }
9  }
10})

这里terser提供的preamble选项,类似于BannerPlugin的raw选项,是不会自动转成注释的。所以需要手动改成注释的形式,一般在每行的前面加双斜杠就好了。