I have a problem with writing a Webpack plugin for a translation service.
The goal is to:
- Get names (and source code) of all required modules during compilation. I need to be able to scan the included source code for special
t()
function usage but I want to scan only those modules which will be included in the bundle (which, depending on build configuration, can be a subset of all project modules). - Based on the gathered modules, I want to create additional modules (with translations) on the fly and add them to the bundle. Those modules need to be able to import their own dependencies.
An additional requirement is that the Webpack's code splitting feature should work with the modules created on the fly (I want to extract them to separate files – e.g. bundle.[lang].js
). Also, which may be out of the scope of this question, I must make those chunks with translations optional (so you don't have to load all languages, but just one).
More details can be found in https://github.com/ckeditor/ckeditor5/issues/387.
I've been trying multiple solutions, but Webpack 2's documentation is not very helpful. I can get all the modules by listening to module resolution hooks (before-resolve
), but I don't know when all the dependencies are resolved and I don't know if I can add more modules after that (and how to do that – is addEntry
ok and when I can use it?).
I was also thinking on connecting Webpack plugin and Webpack loader (because the feature I need is pretty similar to Webpack's style-loader), but from the plugin level I can only add path to the loader, not the loader itself, so I can't pass the config object as a parameter – am I wrong?
PS. I use Webpack 2. If the requirements seem strange to you, please see https://github.com/ckeditor/ckeditor5/issues/387 :).
This is a really complex question, but I can show how you can add additional dependencies to specific modules as if those were required from that module. This ensures that your added modules will be in the correct chunks and will also be removed if the parent module is removed from the bundle.
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))
}
}
}
}
This is just one part of it. You'll also likely need to write your own loader to actually generate the translations (you can replace my-dependency
above with my-loader!path/to/module
to invoke it immediately) and some step after the chunks are created to perhaps extract them into a new asset and load them since they aren't actually require
d anywhere.
来源:https://stackoverflow.com/questions/41869498/how-to-write-webpack-plugin-which-adds-modules-to-the-bundle-on-the-fly-based-on