Closed natew closed 6 years ago
Ok, so getting interesting results. I'd like this:
./layout.html
./icon.png
./main.js
layout:
<!DOCTYPE html>
<html>
<head>
<link rel="apple-touch-icon" href="icon.png"/>
</head>
<body></body>
</html>
main.js
require('./layout.html');
loader:
{ test: /\.html$/, loader: 'html-loader!file-loader?name=index.html' }
And the output to be:
index.html
XXXX.png
where index.html has the path to the icon properly inserted.
But I've tried a variety of combinations. Without the file-loader
it outputs the icon.png but no layout. With file-loader the layout but no icon.
You cannot combine html-loader and file-loader this way.
You can send a PR adding this syntax, but restrict it to known rel
s as not every link
should be processed.
I can't get the build to output the html and the png together, even without file-loader renaming. That should be possible, right? Even just using <img src="icon.png" />
it just outputs the html file.
+1
:+1:
:+1:
+1
+1
+1
+1
+1
+1
Just for reference, I ended up using react helmet in my solutions. :)
:+1:
Also, what about <meta property="og:image" content="someimage.jpg" />
?
Sounds reasonable. We probably need a more configurable solution. I think, there is an infinite number of possible tags which reference other files :)
Very true, a custom function that gets passed all the tags would be really nice! (Similar to how postcss works maybe?)
Currently I'm doing the following trick:
{
test: /\.html$/,
loader: ExtractTextPlugin.extract('html?attrs=link:href')
},
@DaZzz I'm pretty sure that's not a trick, that's intended usage of that option, but we need a better solution for tags like <meta property="og:image" content="someimage.jpg" />
.
+1
Until there is no other solution, interpolation syntax may be used (with interpolate flag turned on):
<link rel="shortcut icon" href="${require('./favicon.ico')}">
<meta property="og:image" content="${require('./someimage.jpg')}" />
And, of course, loaders should be configured appropriately:
...
module: {
loaders: [
...
{
test: /\.(ico|png|eot|svg|ttf|woff|woff2)$/,
loader: 'file?name=[name]-[hash:6].[ext]'
},
...
]
},
...
posthtml maybe :) ?
@vbarbarosh That's actually pretty interesting, what is the result like?
@resistdesign As expected: ./favicon.ico
and ./someimage.jpg
will be copied into the destination directory, and the whole expression will be replaced by path to the file (e.g. ${require('./favicon.ico')}
will be replaced by favicon-123456.ico
).
Can we add an option to treat all attribute values starting with ./
as ones to be resolved by loaders?
Or even make it a default.
I imagine this would satisfy most use cases without explicit attribute whitelists unless I’m missing something.
@gaearon Interesting, does that work for icons, js, css, manifest and all that? It just might. You have to also consider ../
and things like that in case of relative paths, but I guess you could still have ./../
which is wonky but should work.
So what would be the result, it would run the file through a loader and return the new path/URL? The loader CAN'T return code or content because the result will be set as the value of an attribute. I mean it could be a data URL but that seems problematic for code and such I would think.
Currently, we have a mixture between sane defaults (all src
attributes) and additional opt-ins. @gaearon 's suggestion is to extend the sane default to all attribute values that look like a path. We can make the pattern a little bit smarter, for instance, we could also enforce a file extension at the end of the path (like \.[a-z]{3,4}$
).
This would be nice, because it reduces the need to configure things and many instances will just work out of the box. But we would still need to provide a way to exclude certain attributes because there are always exceptions and people will come and say: "Oh, webpack should not handle these kind of attributes".
FYI we decided to stop using html-loader completely and just tell people to maintain a "public" folder for assets that go with HTML. Worked great for us.
The biggest issue I couldn't figure out how to resolve are JSON files. When used in <link>
I want them to be treated as files, not JS modules. On the other hand I don't want user to write !!file!./something.json
. So I decided the whole abstraction is leaky for our use case, and dropped it.
Totally understandable. It doesn't make sense to handle JSONs as javascript modules when referenced from an HTML file. Sometimes, it makes sense to express that as a directory-specific rule (like "all JSONs inside this directory should be emitted as separate files"), but the current way of configuring loaders lacks this type of expression.
Webpack 2 has more powerful way to configure these loader rules. Now you can define loader rules based on the "issuer" which is the module that contains the import statement. Your use-case would be solved like this:
module: {
rules: [
{
test: /\.json$/,
issuer: /\.html$/,
loader: "file-loader"
}
]
}
Very neat.
I have solve it like this,but not pure html-loader,I make it with html-webpack-plugin
<link rel="apple-touch-icon" sizes="114*114" href="<%= require('../assets/images/logo.png') %>">
<link rel="icon" type="image/x-icon" href="<%= require('../assets/images/favicon.ico') %>" sizes="48x48">
loaders = [
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
exclude: '/nolimit/',
loader: 'url-loader',
query: {
limit: 10,
name: utils.assetsPath('img/[name].[hash:6].[ext]')
}
},
{
test: /.(ico)$/,
loader: 'file?name=[name].[hash:6].[ext]'
}
]
then the finally rendered html like this
<link rel="apple-touch-icon" sizes="114*114" href="static/img/logo.32893a.png">
<link rel="icon" type="image/x-icon" href="favicon.aacd9e.ico" sizes="48x48">
@baotang I doubt this will work with the html-loader. For it to work set interpolate: 'require'
option and use ${require('./image.png')}
:
somehwere in the WebPack config:
module: {
loaders: [
//..
{
test: /\.html$/,
loader: 'html',
query: {
interpolate: 'require'
}
] //..
}
And then:
<link rel="apple-touch-icon" sizes="114*114" href="${require('static/img/logo.32893a.png')">
<link rel="icon" type="image/x-icon" href="${require('favicon.aacd9e.ico')" sizes="48x48">
This works for me.
Hi, it is not very clear to me, is link:href
supported? I am trying
<link rel="icon" type="image/x-icon" href="./favicon.ico" >
But does not get picked up by webpack.
I have all the suggestions from this topic, none has worked. Probably it is because I am on webpack 5, and many things have changed since then. I have ended up adding link:href
to the attributes, works fine. I just wonder why it is not added by default, what was the concern there?
@ChoppinBlockParty could you humour me with the complete webpack config snippet I need to do this using todays tool versions? Thanks
@trullock, and for anybody who may come across this in the future if it hasn't been fixed, this works as of webpack 5.21.2:
{
test: /\.html$/i,
loader: 'html-loader',
options: {
attributes: {
list: [
'...',
{
tag: 'link',
attribute: 'href',
type: 'src',
}
]
}
}
}
Wanting to use it with a template that has this in the
head
tag:But it doesn't seem to pick it up! The syntax seems simple enough to add.. want a pull request?