Webpack:在缩小的 JS 文件中插入标头 [英] Webpack: Insert header in minified JS file

查看:39
本文介绍了Webpack:在缩小的 JS 文件中插入标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我缩小的 JS 文件顶部插入一个标题(评论).

I am trying to insert a header (comment) on top of my minified JS files.

const banner: [
    '/**!',
    `@name    : ${package.name}`,
    `@version : ${package.version}`,
    `@date    : ${new Date().getUTCDate()}/${new Date().getUTCMonth() + 1}/${new Date().getUTCFullYear()}`,
    '*/'
    ].join('\n');

为此,我使用了 webpack.bannerPlugin.

new webpack.BannerPlugin({
    banner: banner,
    raw: true,
    entryOnly: true
})

但现在我正在强迫这个问题,横幅似乎被 babelMinifyPlugin 的缩小过程删除了.我尝试使用正则表达式,但它没有解决我的问题.

But now I am forcing the issue that the banner seems to be removed by the minification process of babelMinifyPlugin. I tried to use a Regex but it did not fix my problem.

new babelMinifyPlugin({}, {
    comments: '/^\**!|@name|@version|@date/'
}),

我不确定插件中的正则表达式实际上是如何工作的.对我来说,它应该通过所有以

I am not quiet sure how the Regex in the Plugin actually works. For me, it should pass all comments which begin with

  • /*!,/**!, ... 或
  • @name
  • @version
  • @date
  • /*!,/**!, ... or
  • @name or
  • @version or
  • @date

但这不会发生.当我使用我的开发配置(没有缩小)时,横幅被正确插入,但是当我将它与我的生产配置(有缩小)一起使用时,它没有被添加.那么 babelMinifyPlugin 的正则表达式实际上是如何工作的?

But this not happens. The banner is inserted properly when I use my development config (without minification), but when using it with my production config (with minification) it is not added. So how is the Regex of the babelMinifyPlugin actually working?

推荐答案

为了让你开始在 webpack 配置 JS 文件中声明和定义插件,它钩在发射上,而不是编译(就像 webpack.BannerPlugin,见参考文献).

To get you started in webpack config JS file declare and define plugin, that hooks on emit, not compile (as does webpack.BannerPlugin, see references).

我使用的是 ES2015+(当前的 Node.js LTS,截至撰写本文时为 14 应该能够支持 高达 ES2020) 和 ECMAScript 模块,而不是我的 webpack 配置中的 CommonJS,因此我的示例也是如此,必要时进行翻译.

I'm using ES2015+ (current Node.js LTS which is 14 as of writing should be able to support up to ES2020) and ECMAScript modules, not CommonJS in my webpack config, and thus so will my example, translate if necessary.

// ----------------

import {
  ConcatSource
} from 'webpack-sources';

// ----------------

class BannerAfterMinimizePlugin {
  constructor ({
    banner = '',
    raw = true
  }) {
    this.raw = raw;
    this.banner = raw ? banner : `/*${banner}*/`;
  }

  apply (compiler) {
    compiler.hooks.emit.tapAsync('BannerAfterMinimizePlugin', (compilation, callback) => {
      compilation.chunks.forEach((chunk) => {
        chunk.files.forEach((file) => {
          compilation.updateAsset(
            file,
            (old) => new ConcatSource(this.banner, '\n', old)
          );
        });
      });
      callback();
    });
  }
}

// TODO:
// add key that would result in banner being applied
// only to chunks that satisfy regex
// i.e., to address extensions / chunk names

现在稍后在 webpack 配置中使用它

and now later in the webpack config use it

// ----------------
// BannerAfterMinimizePlugin
if (!tierIsDevelopment) {
  config.plugins.push(new BannerAfterMinimizePlugin({
    banner: fs.readFileSync(
      path.resolve(cjsDirname, 'LICENSE'),
      'utf8'
    ),
    raw: true // LICENCE is already commented
  }));
}
// NOTE:
// in my case cjsDirname is runtime calculated string that points to package root
// construct your paths to file contents you want to bannerise as you see fit
// or just pass inline string as you do in your OP (const banner = [].join('\n');)

请注意,我不像您那样使用 Babel Minify Webpack 插件,而是使用 内置优化工具,即

Note that I do not use Babel Minify Webpack Plugin as you do, but use built in optimisation facilities, i.e.

// ----------------
// OPTIMISATION
config.optimization = {
  minimize: !(tierIsDevelopment || tierIsTesting),
  minimizer: [
    new TerserPlugin({
      test: /\.m?js(\?.*)?$/i,
      // include: '',
      // exclude: '',
      parallel: true,
      // minify: (file, sourceMap) => {},
      extractComments: false,
      // https://github.com/terser/terser#minify-options
      terserOptions: {
        // ecma: undefined,
        // https://github.com/terser/terser#parse-options
        parse: {},
        // https://github.com/terser/terser#compress-options
        compress: {
          drop_console: !(tierIsDevelopment || tierIsTesting)
        },
        // https://github.com/terser/terser#mangle-options
        mangle: false,
        module: false,
        // https://github.com/terser/terser#format-options
        format: {
          comments: false
        },
        sourceMap: false,
        toplevel: false,
        nameCache: null,
        ie8: false,
        // keep_classnames: undefined,
        keep_fnames: false,
        safari10: false
      }
    })
  ]
}

你也应该如此,因为它是DEPRECIATED.

and so probably should you as it is DEPRECIATED.

参考文献:

这篇关于Webpack:在缩小的 JS 文件中插入标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆