I thought a loader is invoked only when some resource is imported or required somewhere and the resources match with such a loader.
But in the following codes, no html file is imported anywhere but the html-loader is still necessary to make the compilation pass because of the underscore template stuff in the html.
So I have the following questions:
Does the plugin use the output of the loader? But the output is just a string and how could it make a difference?
//webpack.config.js
const webpack = require('webpack');
const path = require('path');
const htmlPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './a.js'
},
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.html$/,
loader: "html-loader"
}
]
},
plugins: [
new htmlPlugin({
template:path.resolve(__dirname,'index.html')
})
]
};
//index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script id="item-template" type="text/template">
<label><%= title %></label>
</script>
</body>
</html>
As you said, Webpack only knows about files when you are 'importing' them, otherwise it doesn't know.
However, Webpack first comes into contact with your html file via html-webpack-plugin
. You are probably using html-webpack-plugin
for templating reasons. I am using it purely to allow webpack to insert the generated JS and CSS bundle into the html automatically. My bundle file names contain "hashes" (e.g. bundle.b88ef660a5aa8442f616.js). I don't want to be doing this by hand.
At this point, html-loader
has nothing to do with html-webpack-plugin
. The reason why you might additionally use html-loader
is explained below.
What if your template contains images? What some people do (and it's the wrong thing to do) is use copy-webpack-plugin
to copy the images folder into the output/dist folder and reference any images in the html relative to that folder. This is wrong because you images are bypassing webpack and losing on webpack benefits like adding hashing to image names, optimising images, tree shaking, etc. If you do this, webpack has no idea about your images and you have to manually look after your images folder.
The 'proper' way is to let webpack know about your image dependancies by 'requiring' the images. So instead of <img src="./img/my-image.jpg">
in the html, you should write <img src="${require(
./img/my-image.jpg)}" />
. BUT changing all your images references to the require version is cumbersome, so that's when you use the html-loader
, it will do that automatically for you.
This may cause an error immediately. The error will be something along the lines of Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type
.
All that error means is that webpack doesn't know how to handle images. And to tell webpack how to handle something it doesn't know about, you need to use the appropriate loader. In this case, file-loader
.
Above is the most common use that I have come across of using webpack-html-plugin
and html-loader
.