如何编写Webpack插件,根据其他模块实时添加模块到打包中?

48

我在编写一个翻译服务的Webpack插件时遇到了问题。

目标是:

  1. 在编译期间获取所有必需模块的名称(和源代码)。我需要能够扫描包含特殊t()函数用法的源代码,但我只想扫描将包含在捆绑包中的那些模块(这取决于构建配置,可以是所有项目模块的子集)。
  2. 基于收集的模块,我想动态创建附加模块(带有翻译)并将它们添加到捆绑包中。这些模块需要能够导入自己的依赖项。

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

更多详细信息可以在https://github.com/ckeditor/ckeditor5/issues/387中找到。

我尝试了多种解决方案,但 Webpack 2 的文档并不是很有帮助。我可以通过监听模块解析钩子(before-resolve)来获取所有模块,但我不知道何时解决所有依赖项,也不知道是否可以在此之后添加更多模块(以及如何实现 - addEntry 是否可行,何时可以使用?)。

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

附注:我使用 Webpack 2。如果您认为要求很奇怪,请参见 https://github.com/ckeditor/ckeditor5/issues/387 :)。


这个问题看起来类似于https://dev59.com/eFwZ5IYBdhLWcg3wPOJM - Maciej Bukowski
这也与之相关:https://dev59.com/_lsW5IYBdhLWcg3wVWDj - Maciej Bukowski
如果你说“取决于构建配置”,你是指在其中一个webpack.config文件中设置的内容吗?还是仅基于它所接收到的代码?此外,你可以动态地“require”构建你的语言包,我认为可以使用类似https://www.npmjs.com/package/string-replace-loader的东西。 - user5328504
不幸的是,输出文件应该基于代码创建,因此所有依赖于webpack.config.js文件的方法都不令我满意。字符串替换也不是一个选项,因为我想一次性为每种语言创建翻译文件。 - Maciej Bukowski
这个问题得到了很多赞,但没有答案!!! - thecodejack
1个回答

5

这是一个非常复杂的问题,但我可以展示如何将额外的依赖项添加到特定模块中,就像这些依赖项是从该模块中需要的一样。这确保了您添加的模块将位于正确的块中,并且如果父模块从捆绑包中删除,则这些模块也将被删除。

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-dependency替换为my-loader!path/to/module,以立即调用它),以及在创建块后执行某些步骤,例如将其提取到新资源中并加载它们,因为它们实际上并没有被require


我尝试添加这种依赖关系。所有模块似乎都已创建。但是我缺少类似下面的harmony import部分。这将导致在执行整个 bundle 时发生依赖问题。因为一些子依赖项可能还没有准备好父模块。/* harmony import / var xxx_js__WEBPACK_IMPORTED_MODULE_0__ = webpack_require(/! ./xxx.js */ "./src/xxx.js"); - Sheng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接