Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to pass extra plugins to the child compilation #1818

Open
Knagis opened this issue Aug 9, 2023 · 5 comments
Open

Ability to pass extra plugins to the child compilation #1818

Knagis opened this issue Aug 9, 2023 · 5 comments

Comments

@Knagis
Copy link
Contributor

Knagis commented Aug 9, 2023

Is your feature request related to a problem? Please describe.

I want my template to be able to use require("./file.css"). My css-loader generates hashed classnames that i want to be able to reference in the html template.

However, this doesn't work when mini-css-extract-plugin is used:

Error: No module factory available for dependency type: CssDependency

Describe the solution you'd like

This can be fixed by passing new MiniCssExtractPlugin() to the child compiler:

    const childCompiler = mainCompilation.createChildCompiler(compilerName, outputOptions, [
      // Compile the template to nodejs javascript
      new NodeTargetPlugin(),
      new NodeTemplatePlugin(),
      new LoaderTargetPlugin('node'),
      new webpack.library.EnableLibraryPlugin('var'),
      new (require("mini-css-extract-plugin"))({
        filename: "../../tmp/wp-unused/html/[name].css",
        chunkFilename: "../../tmp/wp-unused/html/[id].css",
      }),
    ]);

So if html-webpack-plugin would allow me to pass additional webpack plugins for the child compilation, this scenario could be enabled without much issue. The css plugin does generate another copy of the extracted file, but as in the sample above, i can send that to some void location to avoid duplicates in the output. Or i could try and configure the plugin to actually write the .css output that is then used by the html page, but that is out of the scope of this ticket.

This would be a very generic, advanced-use-only feature that could potentially be used for many different purposes.

new HtmlWebpackPlugin({
    filename: "index.html",
    template: "index-generator.ts",
    templateCompilerPlugins: [
        new MiniCssExtractPlugin({}),
    ],
}),
@webdiscus
Copy link

@Knagis if you want to use source files of styles and scripts directly in your template, try to use the html-bundler-webpack-plugin.
The plugin detects all source files referenced in a template and extracts processed assets to the output directory.

<html>
<head>
  <!-- specify source style files -->
  <link href="./styles.scss" rel="stylesheet">
  <!-- specify source script files here and/or in body -->
  <script src="./main.js" defer="defer"></script>
</head>
<body>
  <h1>Hello World!</h1>
  <!-- specify source image files -->
  <img src="./picture.png">
</body>
</html>

@Knagis
Copy link
Contributor Author

Knagis commented Aug 13, 2023

Gettings the chunk data in the generated html isn't an issue, i can use the compilation object that the template gets to read the args.

In my case i want to make use of the hashes css class names inside of the html template, that is, instead of having <body class="foobar"> in the html i want to have <body class="foobar-a1b2c3"> - which can be achieved by importing the .css file into the template - but it requires the css plugin to be added to the child compilation that compiles the template

@alexander-akait
Copy link
Collaborator

@Knagis Hello, sorry for delay, still valid?

@Knagis
Copy link
Contributor Author

Knagis commented Dec 19, 2023

Yes, i am currently using a patch for the plugin with great success, of course having the ability to provide the compiler plugins in config would still be better.

diff --git a/lib/child-compiler.js b/lib/child-compiler.js
index ea899c05904e04f4fe6df916ebd3a59e0dd94ea9..9ae444787f51871b289acc62109dd372cc555473 100644
--- a/lib/child-compiler.js
+++ b/lib/child-compiler.js
@@ -106,7 +106,12 @@ class HtmlWebpackChildCompiler {
       new NodeTargetPlugin(),
       new NodeTemplatePlugin(),
       new LoaderTargetPlugin('node'),
-      new webpack.library.EnableLibraryPlugin('var')
+      new webpack.library.EnableLibraryPlugin('var'),
+      new (require("mini-css-extract-plugin"))({
+        filename: "../../tmp/wp-unused/html/[name].css",
+        chunkFilename: "../../tmp/wp-unused/html/[id].css",
+      }),
+      ...mainCompilation.compiler.options.plugins.filter(o => o instanceof webpack.DefinePlugin),
     ]);
     // The file path context which webpack uses to resolve all relative files to
     childCompiler.context = mainCompilation.compiler.context;

@alexander-akait
Copy link
Collaborator

@Knagis Do you want to send a PR? Another idea is to make a hook for such cases, so you can modify more things, we can pass compilation into the hook

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants