首页 文章

如何编写基于其他模块动态添加模块的Webpack插件?

提问于
浏览
42

我在为翻译服务编写Webpack插件时遇到问题 .

目标是:

  • 在编译期间获取所有必需模块的名称(和源代码) . 我需要能够扫描包含的源代码以获取特殊的 t() 函数用法,但我想只扫描那些将包含在bundle中的模块(根据构建配置,它可以是所有项目模块的子集) .

  • 基于收集的模块,我想动态创建其他模块(带翻译)并将它们添加到捆绑包中 . 这些模块需要能够导入自己的依赖项 .

另一个要求是Webpack的代码拆分功能应该与动态创建的模块一起使用(我想将它们提取到单独的文件中 - 例如 bundle.[lang].js ) . 此外,这可能超出了这个问题的范围,我必须使这些翻译块可选(因此您不必加载所有语言,只需加载一个) .

更多细节可以在https://github.com/ckeditor/ckeditor5/issues/387找到 .

我've been trying multiple solutions, but Webpack 2'的文档不是很有帮助 . 我可以通过监听模块分辨率挂钩( before-resolve )来获取所有模块,但是我不知道我之后是否可以添加更多模块(以及如何做到这一点 - 是 addEntry 确定以及何时可以使用它?) .

我还在考虑连接Webpack插件和Webpack加载器(因为我需要的功能非常类似于Webpack's style-loader),但是从插件级别我只能添加路径到加载器,而不是加载器本身,所以我无法通过配置对象作为参数 - 我错了吗?

PS . 我使用Webpack 2.如果您的需求看起来很奇怪,请参阅https://github.com/ckeditor/ckeditor5/issues/387 :) .

1 回答

  • 4

    这是一个非常复杂的问题,但我可以展示如何向特定模块添加其他依赖项,就好像那些模块需要这些依赖项一样 . 这可确保您添加的模块将处于正确的块中,如果从模块中删除父模块,也将删除这些模块 .

    const CommonJsRequireDependency = require("webpack/lib/dependencies/CommonJsRequireDependency")
    
    class MyPlugin {
      apply(compiler) {
        compiler.plugin("compilation", compilation => {
          compilation.plugin("succeed-module", module => {
            // this will be called for every successfully built module, but before it's parsed and
            // its dependencies are built. The built source is available as module._source.source()
            // and you can add additional dependencies like so:
            module.dependencies.push(new CommonJsRequireDependency("my-dependency", null))
          }
        }
      }
    }
    

    这只是其中的一部分 . 您可能还需要编写自己的加载器来实际生成翻译(您可以使用 my-loader!path/to/module 替换上面的 my-dependency 以立即调用它)并在创建块之后的一些步骤可能将它们提取到新资产并加载它们,因为它们在任何地方实际上都不是 require .

相关问题