【问题标题】:How to save contenthash in webpack configuration如何在 webpack 配置中保存 contenthash
【发布时间】:2020-12-21 21:43:29
【问题描述】:

我之前将 webpack 的 [hash] 值保存到了一个 meta.json 文件中:

class MetaInfoPlugin {
  constructor(options) {
    this.options = { filename: 'meta.json', ...options };
  }

  apply(compiler) {
    compiler.hooks.done.tap(this.constructor.name, (stats) => {
      const metaInfo = {
        // add any other information if necessary
        hash: stats.hash
      };
      const json = JSON.stringify(metaInfo);
      return new Promise((resolve, reject) => {
        fs.writeFile(this.options.filename, json, 'utf8', (error) => {
          if (error) {
            reject(error);
            return;
          }
          resolve();
        });
      });
    });
  }
}

module.exports = {
  mode: 'production',
  target: 'web',
...
  plugins: [
    new MetaInfoPlugin({ filename: './public/theme/assets/scripts/meta.json' }),
  ],
...
};

升级到 webpack 5 后,我收到了弃用通知,指出要改用 contenthash 或其他值。

[DEP_WEBPACK_TEMPLATE_PATH_PLUGIN_REPLACE_PATH_VARIABLES_HASH] DeprecationWarning: [hash] is now [fullhash] (also consider using [chunkhash] or [contenthash], see documentation for details)

但是将上面的.hash 部分与.contenthash 或任何其他哈希值交换将不起作用。如何将 contenthash 保存到文件中,以便以后可以在模板系统中使用该值来链接文件?

我基本上试图将[contenthash] 值放入一个文本文件(json,无论格式)中,以便稍后在 PHP 模板系统中重用。

【问题讨论】:

    标签: webpack webpack-5


    【解决方案1】:

    弃用通知即将使用[contenthash] 作为输出文件名。差不多:

    // ...
    output: {
        path: path.resolve(process.cwd(), 'dist'),
        filename: utils.isProd() ? '[name].[contenthash].js' : '[name].js',
        // ...
    },
    

    创建 filelist.json

    使用自己的插件将编译后的文件名写入 webpacks 输出文件夹:

    class FileListPlugin {
        apply(compiler) {
            compiler.hooks.emit.tapAsync('FileListPlugin', (compilation, callback) => {
                var a = { files: [] };
    
                // build filename array
                for (var filename in compilation.assets) 
                    a.files.push(filename);
                
                // build js and css childs
                for (var filename in compilation.assets) {
                    var f = filename.split('.');
                    var filetype = f[f.length - 1];
                    if (filetype === 'css' || filetype === 'js')
                        a[filetype] = {
                            filename: filename,
                            hash: f[f.length - 2]
                        };
                }
    
                // a to string
                a = JSON.stringify(a);
    
                // Insert this list into the webpack build as a new file asset:
                compilation.assets['filelist.json'] = {
                    source: () => { return a },
                    size: () => { return a.length }
                };
    
                callback();
            });
        }
    }
    

    这是对这个例子的修改https://webpack.js.org/contribute/writing-a-plugin/#example

    注册插件:

    plugins: [
        //...
        new FileListPlugin(),
        //...
    ]
    

    filelist.json 的内容如下所示:

    {
        "files": [
            "main.d060b15792a80dc111ee.css",
            "main.0f88c5f5cb783c5a385f.js",
            "layout.pug"
        ],
        "css": {
            "filename": "main.d060b15792a80dc111ee.css",
            "hash": "d060b15792a80dc111ee"
        },
        "js": {
            "filename": "main.0f88c5f5cb783c5a385f.js",
            "hash": "0f88c5f5cb783c5a385f"
        }
    }
    

    【讨论】:

    • 我忘记将此标记为正确答案,抱歉。该解决方案现在开始引发另一个警告:(节点:831376)[DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning:Compilation.assets 将来会被冻结,所有修改都已弃用。重大更改:在密封编译后,Compilation.assets 不应再发生更改。更早地对资产进行更改,例如。 G。在 Compilation.hooks.processAssets 中。确保从 Compilation.PROCESS_ASSETS_STAGE_* 中选择适当的阶段。这不应该适用于这个解决方案,因为没有任何变化?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    • 2023-04-01
    • 2019-06-09
    • 1970-01-01
    • 2020-11-30
    • 1970-01-01
    相关资源
    最近更新 更多