Webpack 插件:编译后如何修改和重新解析模块? [英] Webpack plugin: how can I modify and re-parse a module after compilation?

查看:29
本文介绍了Webpack 插件:编译后如何修改和重新解析模块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 webpack 插件,但不知道如何在构建过程中修改模块.我正在尝试做什么:

I'm working on a webpack plugin and can't figure out how to modify a module during the build. What I'm trying to do:

  • 通过自定义加载器收集数据(很好)
  • 加载所有模块后,收集我的加载器收集的数据(很好)
  • 将我生成的代码插入到构建中的现有模块中(按如下所述执行此操作,不确定这是否是最佳方法)
  • '更新'那个模块,以便我添加的代码得到解析,并将其'require'变成webpack require调用(不知道如何正确执行此操作)

目前我在编译器上使用this-compilation",然后在编译时使用additional-chunk-assets".获取第一个块(目前唯一的块,因为我仍在开发中),遍历该块中的模块以找到我想要修改的模块.然后:

Currently I'm hooking into 'this-compilation' on the compiler, then 'additional-chunk-assets' on the compilation. Grabbing the first chunk (the only one, currently, as I'm still in development), iterating through the modules in that chunk to find the one I want to modify. Then:

  • 将我生成的源附加到模块的 _cachedSource.source._source._value(我也尝试附加到模块的 ._source._value)
  • 将 ._cachedSource.hash 设置为空字符串(因为这似乎是下一步工作所必需的)
  • 我将模块传递给 .rebuildModule()

看起来rebuildModule 应该重新解析源代码,重新建立依赖项等等,但它没有解析我的require 语句并将它们更改为webpack requires.构建的文件包含我修改过的源代码,但 require('...') 语句未修改.

It looks like rebuildModule should re-parse the source, re-establish dependencies, etc. etc., but it's not parsing my require statements and changing them to webpack requires. The built file includes my modified source but the require('...') statements are unmodified.

如何使我修改的模块更新",以便 webpack 将我添加的源与最初解析的源相同?除了rebuildModule(),我还需要做些什么吗?我在构建过程中做这项工作是否太晚了?还是我的方法不对?

How can I make the module I modified 'update' so that webpack will treat my added source the same as the originally parsed source? Is there something I need to do in addition to rebuildModule()? Am I doing this work too late in the build process? Or am I going about it the wrong way?

推荐答案

我想出了如何以一种非常轻松的方式做到这一点.

I figured out how to do this in a pretty painless fashion.

我做错的事情:

  • 可能上钩太晚了?最早可以完成此操作的插件是编译的密封"插件.尽管有这个名字,这个插件钩子是作为密封函数的第一行执行的,所以还没有发生密封.至此,所有模块都已加载完毕.
  • rebuildModule() 不是一个好主意,因为这会从头开始重新加载模块:文件的源被加载并通过任何适用的加载器,并且 _sourcemodule 对象的 code> 属性最终会在该过程完成时重新分配.
    • 此时使用 rebuildModule() 实际上会很棒,如果有一种方法可以修改在此调用中加载的模块源(即动态分配仅用于这次重建).然后我们就可以利用加载模块源时发生的 sourceMap 行为(见下文)
    • probably hooking in too late? the earliest plugin where you can accomplish this is the compilation's 'seal' plugin. Despite the name, this plugin hook executes as the very first line in the seal function, so no sealing has yet occurred. At this point all the modules have been loaded.
    • rebuildModule() isn't a good idea, because this re-loads the module from scratch: the file's source is loaded and passed through any applicable loaders, and the _source property of the module object is eventually reassigned when that process is finished.
      • Using rebuildModule() at this point would actually be great if there were a way to modify the module source as it was being loaded in this call (i.e. dynamically assign a loader function that's only used on this rebuild). We'd then be able to take advantage of the sourceMap behavior that happens when a module's source is loaded (see below)

      我是如何让它工作的:

      • 挂钩compilation的'seal'插件,遍历编译的module并找到你想要的
      • 修改模块的源代码,例如module._source._value += extraCode;
      • 重新解析模块:

      • hook into compilation's 'seal' plugin, iterate through the compilation's modules and find the one you want
      • modify the module's source, e.g. module._source._value += extraCode;
      • reparse the module:

      module.parse.parse(module._source.source(), {
        current: module, 
        module.module,
        compilation: compilation,
        options: compilation.options
      });
      

    • 解析取自 NormalModule 的 build 方法,该方法在正常模块构建过程中加载源后立即或多或少地调用.

      The parsing is taken from NormalModule's build method, which is called more or or less immediately after the source has been loaded during the normal module build process.

      此实现将修改和解析的源代码添加到我的最终输出中.由于在 NormalModuleMixin 的 doBuild 方法中有一些 sourceMap 的东西,而且由于我是在调用这些函数后添加到源中的,所以我认为 sourceMap 现在会被搞砸.因此,下一步是获取 sourceMap 以反映代码添加.不确定是否尝试手动更新 sourceMap 或查看上面的想法,尝试动态应用加载程序并调用重建模块()而不是解析.

      This implementation gets the modified and parsed source into my final output. Since there's some sourceMap stuff in NormalModuleMixin's doBuild method, and since I'm adding to the source after those functions have been called, I assume the sourceMap will be messed up now. So, next step is getting the sourceMap to reflect the code addition. Not sure whether to try and manually update the sourceMap or look into the idea above, trying to dynamically apply a loader and call rebuildModule() instead of parsing.

      如果您知道执行上述任何一项的更好方法,请告诉我!

      If you know a better way of doing any of the above, please let me know!

      这篇关于Webpack 插件:编译后如何修改和重新解析模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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