Cache and file watcher does not detect changes in `posthtml-component` files
π Bug Report
For some context, posthtml-component is a fairly popular PostHTML plugin that allows us to treat HTML partials like components (i.e., prop merging, slots, etc.). Consider the following index.html below for example:
<!-- The `x-hello` element here is substituted by some `hello.html` somewhere. -->
<!-- Props and slots are also passed into the `hello.html` partial accordingly. -->
<x-hello hello="1" world="1">
Wow! Cool slots!
</x-hello>
Parcel works great when we edit the index.html file itself. The problem arises when we edit the hello.html component. In this case, no changes are detected by the entire build system. That is:
- The cache is not invalidated.
- The file watcher doesn't refresh accordingly.
- Because of this, the dev server also never refreshes.
Given that the cache is never invalidated, the problem persists across multiple invocations of parcel serve. The dev server boots up really fast, which is great most of the time, but not what we want in this case because this means Parcel reused its stale .parcel-cache/.
In an attempt to debug the issue, I tried deleting the .parcel-cache/ folder, which worked! π₯³ But I'll be completely honest here, I would much rather not manually close the dev server, delete the .parcel-cache/ folder, and then run parcel serve again just to see the changes in hello.html reflect in the page.
π Configuration (.babelrc, package.json, cli command)
// .posthtmlrc
{ "plugins": { "posthtml-component": { } } }
// package.json
{
// Package metadata omitted for brevity.
"source": "index.html",
"devDependencies": {
"parcel": "^2.9.3",
"posthtml-component": "^1.1.0"
}
}
No other configurations follow. We use the default .parcelrc from @parcel/config-default.
π» Code Sample
Based on the provided configuration above, I present a minimal reproducible example here.
[!NOTE] Assume that all files are in the same directory as the configuration files.
<!-- index.html -->
<html>
<body>
<!-- Editing the call site works perfectly fine! π₯³ -->
<x-hello>Test</x-hello>
</body>
</html>
<!-- hello.html -->
<!-- Editing the component itself is problematic. π -->
<p>
<!-- The `yield` is specific to `posthtml-component`. -->
<yield></yield>
</p>
π€ Expected Behavior
As mentioned above, I expect that any changes in index.html and hello.html should be picked up by the file watcher, then invalidated in the cache, then recompiled by the build system, and finally refreshed by the dev server.
Moreover, when running parcel serve again after making changes to index.html or hello.html, I expect the build system to pick up on the changes and invalidate the cache accordingly.
π― Current Behavior
The entire pipeline works perfectly fine when editing the call site of the component (i.e., index.html).
It is hello.html that is problematic. First, parcel serve does not detect new edits, thereby persisting a stale cache. Second, succeeding invocations of parcel serve does not cause a recompilation despite changes in hello.html.
π Possible Solution
The problem may be worked around in three ways (neither of which are ideal):
- Delete the
.parcel-cache/beforehand. - Re-run the dev server with
--no-cachefor each edit ofhello.html. - Edit
index.htmlso that the PostHTML pipeline re-executes.
Now, I suspect that this bug is somewhat related to #5453. Given that PostHTML plugins are somewhat opaque to Parcel (especially when they implement custom module resolution like that in posthtml-component), I fear that I may have encountered an inherent limitation of Parcel's integration with PostHTML.
In other words, I believe that the naΓ―ve text substitution of the posthtml-component plugin preprocesses the HTML in such a way that does not preserve information about the dependencies (i.e., hello.html). Parcel's module resolution thus fails to observe hello.html because from Parcel's perspective, it only sees the preprocessed index.html (never the hello.html dependency).
With that said, I would love to know if there is anything that can be done to resolve or work around this issue aside from the three non-solutions I proposed earlier?
- Is there anything I can do in my project configuration as a temporary workaround?
- Is there anything we can tweak in Parcel's PostHTML pipeline that allows us to better observe "hidden" dependencies?
- Is there anything that can be changed in the
posthtml-componentplugin itself so that it can better preserve dependency information? - Would a dedicated Parcel plugin whose sole purpose is to artificially insert a dependency help here? Of course, its output would be an empty string. The goal is to simply manually insert the "hidden" dependency.
π Your Environment
| Software | Version(s) |
|---|---|
| Parcel | 2.9.3 |
| Node | 20.5.1 |
| pnpm | 8.6.12 |
| Operating System | Windows 10 |
Related:
https://github.com/posthtml/posthtml-modules/pull/100
https://github.com/thewebartisan7/posthtml-components/issues/19
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs.