I understand that this looks like it should be addressed to mini-css-extract-plugin's issues. But it's already been done. They don't seem to agree that it's within their scope to address this.
Do you agree with that? Is there already an option to achieve this with html-webpack-plugin?
All we're asking is an option to specify where we'd want our <link> tag to be inserted in the html template.
Currently it goes in the <head>, and what satisfies my usecase is having the option to insert it at the end of the <body> tag.
Thanx!
You can set inject:false.
This will disable any modification of your template and allows you to add the link and script tags by yourself.
If you use the build in default template loader this would look like this (simplified):
<html>
<body>
<%= assetTags.headTags %>
<%= assetTags.bodyTags %>
</body>
</html>
headTags contains: an array of link and meta tags
bodyTags contains: an array of script tags
All available parameters are generated here:
Hey there, thanx a lot for the direction!
Is this possible with v3.2.0?
I tried updating to v4, but I'm using Favicons Webpack Plugin, which is incompatible with it.
@Birowsky there is an easy way solution, here you go.
Webpack config
new HtmlWebpackPlugin({
inject: false,
template: '----YOUR-INDEX----',
}),
For CSS on
<%= htmlWebpackPlugin.files.css.map(href =>
'<link href="' + href + '" rel="stylesheet">'
).join('\n') %>
For Javascript on
<%= htmlWebpackPlugin.files.css.map(href =>
'<script type="text/javascript" src="' + href + '"></script>'
).join('\n') %>
I finally got around trying this, but I'm facing an error:
ERROR in Error: Child compilation failed:
Module build failed (from ../node_modules/ejs-compiled-loader/index.js):
NonErrorEmittedError: (Emitted value instead of an instance of Error) Unexpected token: operator (>) (line: 40, col: 2737, pos: 10104)
Error
```
Here's how my config looks like:
new HtmlWebpackPlugin({
inject: false,
template: './app.ejs',
filename: 'index.html',
})
<details><summary>Further log output</summary>
<p>
parse-js.js:263 new JS_Parse_Error
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:263:18
parse-js.js:271 js_error
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:271:11
parse-js.js:733 croak
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:733:9
parse-js.js:740 token_error
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:740:9
parse-js.js:746 unexpected
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:746:9
parse-js.js:1124
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1124:9
parse-js.js:1209 maybe_unary
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1209:19
parse-js.js:1236 expr_ops
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1236:24
parse-js.js:1240 maybe_conditional
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1240:20
parse-js.js:1264 maybe_assign
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1264:20
parse-js.js:1268 maybe_assign
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1268:60
parse-js.js:1278
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1278:20
parse-js.js:1135 expr_list
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1135:24
parse-js.js:1198 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1198:48
parse-js.js:1190 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1190:20
parse-js.js:1190 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1190:20
parse-js.js:1190 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1190:20
parse-js.js:1122
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1122:20
parse-js.js:1209 maybe_unary
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1209:19
parse-js.js:1236 expr_ops
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1236:24
parse-js.js:1240 maybe_conditional
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1240:20
parse-js.js:1264 maybe_assign
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1264:20
parse-js.js:1278
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1278:20
parse-js.js:1281
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1281:36
parse-js.js:1312 prog1
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1312:15
parse-js.js:1104
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1104:35
parse-js.js:1209 maybe_unary
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1209:19
parse-js.js:1236 expr_ops
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1236:24
parse-js.js:1240 maybe_conditional
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1240:20
parse-js.js:1264 maybe_assign
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1264:20
parse-js.js:1278
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1278:20
parse-js.js:1135 expr_list
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1135:24
parse-js.js:1198 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1198:48
parse-js.js:1122
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1122:20
parse-js.js:1209 maybe_unary
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1209:19
parse-js.js:1236 expr_ops
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1236:24
parse-js.js:1240 maybe_conditional
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1240:20
parse-js.js:1264 maybe_assign
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1264:20
parse-js.js:1278
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1278:20
parse-js.js:1135 expr_list
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1135:24
parse-js.js:1198 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1198:48
parse-js.js:1190 subscripts
[gotaguy-frontend]/[ejs-compiled-loader]/[uglify-js]/lib/parse-js.js:1190:20
NormalModule.js:310 runLoaders
[gotaguy-frontend]/[webpack]/lib/NormalModule.js:310:13
LoaderRunner.js:367
[gotaguy-frontend]/[loader-runner]/lib/LoaderRunner.js:367:11
LoaderRunner.js:233
[gotaguy-frontend]/[loader-runner]/lib/LoaderRunner.js:233:18
LoaderRunner.js:143 runSyncOrAsync
[gotaguy-frontend]/[loader-runner]/lib/LoaderRunner.js:143:3
LoaderRunner.js:232 iterateNormalLoaders
[gotaguy-frontend]/[loader-runner]/lib/LoaderRunner.js:232:2
LoaderRunner.js:205 Array.
[gotaguy-frontend]/[loader-runner]/lib/LoaderRunner.js:205:4
CachedInputFileSystem.js:43 Storage.finished
[gotaguy-frontend]/[enhanced-resolve]/lib/CachedInputFileSystem.js:43:16
CachedInputFileSystem.js:79 provider
[gotaguy-frontend]/[enhanced-resolve]/lib/CachedInputFileSystem.js:79:9
graceful-fs.js:78
[gotaguy-frontend]/[graceful-fs]/graceful-fs.js:78:16
ERROR in Error: Child compilation failed:
Module build failed (from ../node_modules/ejs-compiled-loader/index.js):
NonErrorEmittedError: (Emitted value instead of an instance of Error) Unexpected token: operator (>) (line: 40, col: 2737, pos: 10104)
Error
ERROR in ./app.ejs (../node_modules/html-webpack-plugin/lib/loader.js!./app.ejs)
Module build failed (from ../node_modules/ejs-compiled-loader/index.js):
NonErrorEmittedError: (Emitted value instead of an instance of Error) Unexpected token: operator (>) (line: 40, col: 2737, pos: 10104)
Error
at new JS_Parse_Error (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:263:18)
at js_error (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:271:11)
at croak (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:733:9)
at token_error (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:740:9)
at unexpected (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:746:9)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1124:9
at maybe_unary (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1209:19)
at expr_ops (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1236:24)
at maybe_conditional (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1240:20)
at maybe_assign (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1264:20)
at maybe_assign (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1268:60)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1278:20
at expr_list (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1135:24)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1198:48)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1190:20)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1190:20)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1190:20)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1122:20
at maybe_unary (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1209:19)
at expr_ops (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1236:24)
at maybe_conditional (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1240:20)
at maybe_assign (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1264:20)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1278:20
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1281:36
at prog1 (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1312:15)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1104:35
at maybe_unary (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1209:19)
at expr_ops (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1236:24)
at maybe_conditional (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1240:20)
at maybe_assign (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1264:20)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1278:20
at expr_list (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1135:24)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1198:48)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1122:20
at maybe_unary (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1209:19)
at expr_ops (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1236:24)
at maybe_conditional (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1240:20)
at maybe_assign (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1264:20)
at /{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1278:20
at expr_list (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1135:24)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1198:48)
at subscripts (/{{obfuscated-project-path}}/node_modules/ejs-compiled-loader/node_modules/uglify-js/lib/parse-js.js:1190:20)
at runLoaders (/{{obfuscated-project-path}}/node_modules/webpack/lib/NormalModule.js:310:13)
at /{{obfuscated-project-path}}/node_modules/loader-runner/lib/LoaderRunner.js:367:11
at /{{obfuscated-project-path}}/node_modules/loader-runner/lib/LoaderRunner.js:233:18
at runSyncOrAsync (/{{obfuscated-project-path}}/node_modules/loader-runner/lib/LoaderRunner.js:143:3)
at iterateNormalLoaders (/{{obfuscated-project-path}}/node_modules/loader-runner/lib/LoaderRunner.js:232:2)
at Array.<anonymous> (/{{obfuscated-project-path}}/node_modules/loader-runner/lib/LoaderRunner.js:205:4)
at Storage.finished (/{{obfuscated-project-path}}/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:43:16)
at provider (/{{obfuscated-project-path}}/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:79:9)
at /{{obfuscated-project-path}}/node_modules/graceful-fs/graceful-fs.js:78:16
at FSReqWrap.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:53:3)
```
Have you already tried the FaviconsWebpackPlugin 1.0?
Hey @jantimon! Thanx for the suggestion, didn't notice it got updated.
Just tried it, and what I see is that on inject:false, the FaviconsWebpackPlugin tags are not injected in the html file.
Ohh @Birowsky you are right.. sorry for that - there is work on it already in the FaviconsWebpackPlugin master branch
@jantimon I went ahead and tried your suggestion without FaviconsWebpackPlugin, and I got stuff to report:
One of my goals is to inline a splash.css before the main app.css link tag, so that it would end up looking like:
<style>#splash{...}</style>
<link href="app.923680b9da231095ec17.css" rel="stylesheet">
To inline the splash, I'm using HTMLInlineCSSWebpackPlugin.
To sort the chunks to the desired order, I use chunksSortMode:
const chunkOrder = ['splash', 'app'];
...
chunksSortMode: (a, b) => chunkOrder.indexOf(a) <= chunkOrder.indexOf(b) ? -1 : 1,
However, the desired order is not respected. First comes the "app" chunk, then the "splash" chunk. And that's without the suggested inject: false.
On the other hand, if I set inject: false and also set the injecting points in my template down in the <body> like so:
<%- htmlWebpackPlugin.tags.headTags %>
<%- htmlWebpackPlugin.tags.bodyTags %>
the inlined splash css stays in the <head> and the rest of the chunk assets are injected appropriately in the <body>.
This to me indicates some sort of bug when inlining stuff with HTMLInlineCSSWebpackPlugin, I just don't know who to blame ; )
At this point my goal is achieved, and I also understand that the FaviconsWebpackPlugin issue is not related to this plugin, which means this issue is closable. I'll let you take the executive decision tho.
Thanks for your feedback :)
You can also filter on tag e.g.:
<%= htmlWebpackPlugin
.tags
.headTags
.filter((tag) => tag.tagName === 'meta')
.join('')
%>
That way you might be able to inject only splash
If you are suggesting this as a workaround, don't worry about it. I'm fine with what I got.
If you are suggesting this as a canonical approach to solving this issue, I'm a bit confused. Aren't we supposed to expect that even the inlined chunks are to be injected at the declared injection point?

this maybe can help you
html-webpack-extra-tags-plugin
Maybe this example can be of help:
https://github.com/jantimon/html-webpack-plugin/tree/master/examples/custom-insertion-position
Most helpful comment
@Birowsky there is an easy way solution, here you go.
Webpack config
For CSS on
For Javascript on