reactjs - Webpack 4 到 5 : custom plugin: replacing compilation. assets mutation with compilation.hooks.processAssets

标签 reactjs flask webpack webpack-5

我在使用编译 Hook processAssets 来镜像自定义插件中已弃用的 Webpack 4 功能时遇到问题。

该插件的目的是将 js/css 文件的 chunkhash 写入 python 文件,Flask 服务器使用该文件根据用户的 session 和角色(例如公共(public)、私有(private)、管理员等)。

插件的主要内容( Assets 的直接变异)如下。

compiler.hooks.emit.tapAsync("WriteHashesPlugin", (compilation, cb) => {
    //For each bundle, write the name and the corresponding hash.
    compilation.chunks.forEach(chunk => {
        lines.push("__" + chunk.name + "_hash__ = '" + chunk.renderedHash + "'")
    });
    const content = lines.join("\n");

    compilation.assets[this.filename] = { // <= this.filename = "{relative_path}/bundles.py"
        source: () => content,
        size: () => content.length
    }
    cb();
})

此代码仍然“有效”创建/更新 python 文件,但我当然不想使用已弃用的语法。构建输出中的警告消息:

(node:38072) [DEP_WEBPACK_COMPILATION_ASSETS] DeprecationWarning: Compilation.assets will be frozen in future, all modifications are deprecated.
BREAKING CHANGE: No more changes should happen to Compilation.assets after sealing the Compilation.
        Do changes to assets earlier, e. g. in Compilation.hooks.processAssets.
        Make sure to select an appropriate stage from Compilation.PROCESS_ASSETS_STAGE_*.

我已经实现了 compilation.hooks.processAssets 而不是直接访问 Assets ;但是,我无法让它按预期工作。

compiler.hooks.emit.tapAsync("WriteHashesPlugin", (compilation, cb) => {
    //For each bundle, write the name and the corresponding hash.
    compilation.chunks.forEach(chunk => {
        lines.push("__" + chunk.name + "_hash__ = '" + chunk.renderedHash + "'")
    });
    const content = lines.join("\n");

    // The below code block compiles but doesn't get run
    compilation.hooks.processAssets.tap({
        name: 'WriteHashesPlugin',
        stage: compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
        additionalAssets: true
    }, () => {
        compilation.emitAsset(
            this.filename,
            content
        );
    });
    cb();
})

我已经尝试将 compilation.updateAsset 与阶段 PROCESS_ASSETS_STAGE_ADDITIONS 一起使用,但没有成功。

无论如何我都不是 webpack 专家,但过去几天一直在搜索文档并试图理解源代码。我对我做错了什么的一些想法:

  • compiler.hooks.emit 不是修改 Assets 的编译过程中的适当步骤(也许在编译过程的某个时刻, Assets 不会被改变?)。<
  • compilation.emitAsset 不是要使用的合适的编译钩子(Hook)。
  • 我误解了构建输出中的弃用警告,我应该做一些完全不同的事情。
  • 有一种更好的方法让 Flask 可以使用 chunkhashes。
  • 还有一些你们可以为我阐明的东西。

最佳答案

感谢@chiborg 的评论,我能够通过一些调整使这段代码正常运行。

如本 post 所写,

First, you need to bring in the { sources } class from webpack, which will aid us in crafting raw source changes to an asset (regardless of its optimization or asset type):

const { sources } = require('webpack');

要使用的适当钩子(Hook)是 compiler.hooks.compilation.tap 而不是 compiler.hooks.emit.tapAsync;更改后,必须将 Hook 中的其余代码移至 compilation.hooks.processAssets:

/**
 * Writes build version and bundle hashes to a new file, with the dir
 * specified in this.filename.
 */
compiler.hooks.compilation.tap("WriteHashesPlugin", compilation => {
    compilation.hooks.processAssets.tap({
        name: 'WriteHashesPlugin',
        stage: compilation.PROCESS_ASSETS_STAGE_ADDITIONAL
    }, () => {
        const lines = [];
        // Write build version
        lines.push("__version__ = '" + this.version + "'");
        // For each bundle, write the name and the corresponding hash.
        compilation.chunks.forEach(chunk => {
            lines.push("__" + chunk.name + "_hash__ = '" + chunk.renderedHash + "'");
        });
        const content = lines.join("\n");
        // write bundles.py to assets
        compilation.emitAsset(
            this.filename,
            new sources.RawSource(content)
        );
    });
});

compilation.chunksprocessAssets Hook 之外访问时为空,但将所有内容移入 Hook 使其按预期工作。

关于reactjs - Webpack 4 到 5 : custom plugin: replacing compilation. assets mutation with compilation.hooks.processAssets,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72652370/

相关文章:

javascript - 如何让 axios-cache-adapter 使用 responseType blob 缓存文件下载?

reactjs - 创建 react 应用程序,重新加载不起作用

reactjs - 使用异步操作时 React-Redux 组件测试失败

python - Flask 是否有任何音频流解决方案?

reactjs - React 风格、Webpack、React - 未捕获错误 : Invariant Violation: The `style` prop

vue.js - Vue cli 和 vuetify 如何使用本地 Roboto 字体

reactjs - 在 React-Table 中导出为 PDF

python - 如何编写带有请求的 Flask 装饰器?

python-3.x - 如何使用 Flask/Python 3 处理 URL 中丢失的参数

node.js - 如何使用 aurelia 让 webpack 与 Electron 一起工作?