【问题标题】:Webpack plugin: How to dynamically add a loader to a module?Webpack 插件:如何动态地将加载器添加到模块中?
【发布时间】:2018-02-26 15:58:04
【问题描述】:

我正在编写一个 Webpack 插件。在模块解析期间,这个插件应该为一些模块动态添加一个特定的加载器,但不是全部。

我现在的想法是利用normal-module-factoryafter-resolve 事件。在那里,我可以修改数组data.loaders。一些调试告诉我这个数组包含{ loader: string, options: object | undefined }形式的对象。

我找不到任何关于即时修改每个模块加载器的文档。所以我想知道:

  • 这是正确的方法吗?
  • 一些(但不是全部)现有的loaders 条目包含一个附加属性ident,如下所示:'ref--0-0'。我应该什么时候设置这个属性,使用什么值?

【问题讨论】:

    标签: javascript webpack


    【解决方案1】:

    我不确定这是否是最好的解决方案,但这段代码似乎可以工作:

    class MyPlugin {
      apply(compiler) {
        compiler.plugin('normal-module-factory', normalModuleFactory => {
          normalModuleFactory.plugin('after-resolve', (data, callback) => {
            data.loaders.push({
              loader: ..., // Path to loader
              options: {}
            });
            callback(null, data);
          });
        });
      }
    }
    
    module.exports = MyPlugin;
    

    关于额外的ident 属性:Webpack 需要能够比较加载器选项。默认情况下,它通过在选项对象上调用JSON.stringify() 来完成此操作,然后比较结果字符串。通过添加ident 属性,您可以显式指定选项对象的字符串表示形式。详情请见https://stackoverflow.com/a/49006233/52041

    【讨论】:

      【解决方案2】:

      我试图解决一个类似的问题,并且只想为插件中其他地方标识的特定文件添加一个加载器。我的解决方案如下:

      loader.js

      module.exports = function loader(content) {
        return mySpecialTransformation(content);
      };
      

      插件.js

      const path = require('path');
      
      class MyPluginName {
        apply(compiler) {
          compiler.hooks.compilation.tap('MyPluginName', compilation => {
            compilation.hooks.normalModuleLoader.tap('MyPluginName', (loaderContext, module) => {
              if (myModuleCondition(module)) {
                module.loaders.unshift({
                  loader: path.resolve(__dirname, 'loader.js'), // Path to loader
                  options: {}
                });
              }
            });
          });
        }
      }
      

      请注意,我使用 unshift 而不是 push 来添加加载器 - 我仍处于开发阶段,所以我可能错了,但我目前的理解是我希望加载器在所有“标准”之后运行加载器很可能正在转换打字稿等。我相信加载器是从右到左应用的。取决于你在做什么,这可能并不重要。

      【讨论】:

      • 对于使用 Webpack 5 或更高版本的任何人,请注意 normalModuleLoader 已改为 NormalModule.getCompilationHooks(compilation).loader。见this docs page
      猜你喜欢
      • 1970-01-01
      • 2018-06-05
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 2016-09-10
      • 2016-01-24
      • 2019-01-27
      相关资源
      最近更新 更多