Including html partials within html partials without the interpolate option
Documentation Is:
- [x] Missing
- [ ] Needed
- [x] Confusing
- [ ] Not Sure?
Please Explain in Detail...
At some point in the past html-loader had an interpolate option. This allowed to load partials within partials in templates. As far as understand it this recently got deprecated and replaced with preprocessor.
So, answers like this one aren't working anymore.
A couple of questions like this one asking how to achieve it popped up, but they've gone without answers.
The documentation seems unclear as if this is still possible as the only example mentions handlebars and only shows this implementation within the webpack config.
Your Proposal for Changes
Is there any chance an official explanation of how to achieve this could be provided in the docs or even in this thread? I've tried everything possible and I'm absolutely lost.
I ended up reverting to 0.5.5, which works without any problems. I'm unsure why this breaking change was included without a way to replace it?
Can you provide example how you want to include? You have JS, so you can include anything
Can you provide example how you want to include?
Including already works:
<%= require('html-loader!../components/navbar/index.html') %>
The problem is that without the interpolate option (as well as the root option), if one of the files I include has another inclusion within it, then it won't actually be included. This means I can't have a component within a component which severely limits what's possible.
Why not bring back how it used to work?:
<%= require('html-loader?root=.&interpolate!../components/sidebar/index.html') %>
You have JS, so you can include anything
If I include from JS it will be added client side, which is of course not great for SEO. I need Webpack to build all my files into a single component.
It is out of scope HTML spec, HTML doesn't support <=% require() %=>, so we do not support it, you need loader for this loader, also JS has import and it can be used with it
https://github.com/webpack-contrib/html-loader#preprocessor
You should always return valid HTML
It is out of scope HTML spec, HTML doesn't support
<=% require() %=>, we doesn't support it, you need loader for this loader, also JS hasimportand it can be used with it
The html-loader already supports <=% require() %=>. Either way that's not my point.
I'm not asking to support <=% require() %=>, I'm asking to either:
- Get an entry in the docs to explain how to properly replace
interpolatewithpreprocessorto allow html components - Bring back interpolate so that interpolating html is possible
Which are not out of scope
Get an entry in the docs to explain how to properly replace interpolate with preprocessor to allow html components
We have examples for handlebars/PostHTML, it is a most popular solutions, we can't cover all edge cases
Bring back interpolate so that interpolating html is possible
No interpolating more, if you need it you can create own loader, we support only pure HTML, because it will be part of core webpack, webpack supports non standard stuff only through loaders/plugins
The html-loader already supports <=% require() %=>.
It is just luck that you did not receive an error while parsing.
I strongly recommend migrate on a template system, using require is the bad solution and have many bugs and limitations
Would it be a problem if I spun html-loader 0.5.5 (the last version that supported this) into its own loader?
The demand is there and people clearly prefer using this rather than learning some other templating system. It's also the suggested way by webpack-html-plugin to load partial HTML files, so it seems a bit closeminded to say
It is just luck that you did not receive an error while parsing.
As far as I see it there's not really enough information on how to use preprocessor. It would probably serve the function I'm asking fairly well, it's just unclear how I could set preprocessor to use a normal loader rather than another library to process my files.
On top of that the changelog states:
the interpolate option was removed, please consider migration on the preprocessor
But doesn't offer much explanation on how to do so.
Would it be a problem if I spun html-loader 0.5.5 (the last version that supported this) into its own loader?
Yep, you can do it temporary, but I would advise speed up migration on a template system
The demand is there and people clearly prefer using this rather than learning some other templating system. It's also the suggested way by webpack-html-plugin to load partial HTML files, so it seems a bit closeminded to say
We should remove it from examples
As far as I see it there's not really enough information on how to use preprocessor. It would probably serve the function I'm asking fairly well, it's just unclear how I could set preprocessor to use a normal loader rather than another library to process my files.
Yep, we can improve docs about it.
On top of that the changelog states:
the interpolate option was removed, please consider migration on the preprocessor But doesn't offer much explanation on how to do so.
I provide examples for handlebars/PostHTML, I thought that was enough, maybe improving it for compatibility with other loaders will be great
The crucial part for me to have the included file processed by webpack again before being included. I can include the file with PostHTML, but it only loads the raw file. If there is a way to achieve this could you please explain how?
I can include the file with PostHTML, but it only loads the raw file.
What do you mean?
What do you mean?
I set up posthtml and posthtml-include created a file file1.html with includes ~~<include src="file2.vue"></include>~~<include src="file2.pug"></include>. As output I got the content of ~~file2.vue~~file2.pug insertet into the html of file1.html.
Including the old way processed the content of file2.~~vue~~pug via webpack and the configured loaders.
@philippdieter Maybe you can provide small example of configuration? I want to make sure that I understand you correctly
I made the mistake and mixed up the endings of my files in the post above, I have updated them there, I am sorry.
I build an example located at https://github.com/philippdieter/html-loader-include-sample
The resulting output file is https://github.com/philippdieter/html-loader-include-sample/blob/master/webroot/file1.html
The output possible with include was <h1>Content file1</h1><h1>Content file2</h1> as the included file was processed by webpack, now its <h1>Content file1</h1>h1 Content file2
@philippdieter Thanks, I will look at this tomorrow
Yes, the same problem, here other problems most if loaders for HTML preprocessing returns JS content instead HTML, it's a little wrong, for example postcss-loader return CSS content, not JS, so css-loader + postcss-loader work fine
Ideally pug-loader should return pure HTML for html-loader, here no solutions, only open an issue in pug-loader, even include not help here, it is a fundamental problem.
In theory we can add some magic to html-loader, like:
<div>My Custom Text</div>
<link rel="webpack-import" href="./index.html" />
<div>My Custom Text</div>
Will be compiled to:
import __HTML_LOADER_LINK_IMPORT_1__ from './index.html';
export `<div>My Custom Text</div>` +__HTML_LOADER_LINK_IMPORT_1__ + '<div>My Custom Text</div>';
And extracted to
<div>My Custom Text</div>
<div><img alt="Image" src="./path/to/img.png"><span>Foo</span></div>
<div>My Custom Text</div>
It is HTML compatibility, no problems with require/import, maybe even no lint problems
I would like to hear your opinion.
Other good idea https://github.com/w3c/webcomponents/issues/645
JS has imports/exports, CSS only imports, HTML has not imports/exports :smile:
Just to be sure you looked at the right module: In my example it's pug-plain-loder, not pug-loader. I remember vaguely about having used this loader because it returns html(?). I don't know enough about webpack internals to tell if there is a problem, all I know is that my setup worked with html-loader 0.5.5 and include ':D
I like the idea of the link tag very much.
As far as I understand w3c/webcomponents#645 it's about using includes on client side, right? As my current workflow relies on having the result of the including written into an html file to disk I would much appreciate the solution with the link tag.
Just to be sure you looked at the right module: In my example it's pug-plain-loder, not pug-loader. I remember vaguely about having used this loader because it returns html(?).
Yes, I mean pug-plain-loader.
As far as I understand w3c/webcomponents#645 it's about using includes on client side, right?
Yes :+1:
I would not want to make this part as a separate option or an official solution, as this is still not standardized.
But we can do something small and simple.
We just need improve the attributes option, like:
{
tag: 'include',
attribute: 'src',
type: 'template',
},
You can:
- Using any tags/attributes
- No new options, it is just advanced abilities
- We do not ship new non standard features for HTML
We just need improve the
attributesoption, like:
Having the option to specify a tag even sounds better than having a fixed one. I like this idea very much!
<link rel="webpack-import" href="./index.html" />
I would really like this. Super elegant solution.
Feel free to send a PR, I will do it, but only after next week
Feel free to send a PR, I will do it, but only after next week
I'm not familiar with how html-loader works but I will definitely give it a shot.
I am having the same issue, as I made a lot of use of interpolate too. My situation was like this.
The app has various HTML files that used this syntax to include HTML partials:
<%= require('html-loader?interpolate!../templates/header.html') %>
The example, header.html, uses commands that are parsed by Webpack. For example (removing irrelevant code).
<!doctype html>
<html lang="en">
<head>
<script type="text/javascript">
var appUrl = "${process.env.APP_URL}";
${require("!!raw-loader?esModule=false!uglify-loader!../static/browser-support.js")}
</script>
</head>
<body>
${require("html-loader?interpolate!./nav.html")}
The interpolate feature was very useful. I don't need a templating engine, and it wouldn't really help in this case as I'm using Webpack to embed a JS file too...
Any chance it can be brought back, or is there a workaround?
@ItalyPaleAle no interpolate and never, it is JS-in-HTML and very dirty way and never work fine, with future webpack versions you will get a lot of problems with this, solution was written above
Using:
<script type="text/javascript">
var appUrl = "${process.env.APP_URL}";
${require("!!raw-loader?esModule=false!uglify-loader!../static/browser-support.js")}
</script>
is very terrible, a lot of optimizations was missed + you can't use split chunks correctly, avoid it