When you build an app that has multiple entrypoints which both point to the same JS and CSS file (this is a minimal repro use-case) and also have that JS file point to the same CSS file the html bundle that gets built returns the css bundle path in 2 link tags, the one that was already present and a new one inserted as it's also referenced by the JS. Besides this is also puts that css bundle path in the script tag, where the JS bundle should be referenced.
The script tag should reference the JS bundle and ideally but optionally the CSS bundle should only be referenced once. So basically not add an additional link tag if the css file is already part of the html bundle.
JS does not get loaded and CSS bundle is referenced 3 times.
I solved this by just removing the css reference in the JS file, which is a good solution for this specific use-case as it should really only be referenced once.
But this seems like a bug that could potentially have a larger impact on more useful use-cases.
Tried to debug it as far as I could and got stuck at replaceURLReferences where bundleGraph.getBundlesInBundleGroup(resolved.value) returned 3 bundles with the first being the JS which I wanted to reference in the script tag.
And the css bundle which is both bundle 1 and 2 in the link tag. Maybe this is a bundler bug as these are all the same bundle-group? and it should probably be 2 groups, one for the CSS and one for the JS. I wish I knew more about the graph and bundling logic of Parcel but it's currently a bit of a black box so I should probably focus my efforts towards the parts I know a lot about,
Reproducible example: (also made a branch with a test-case: https://github.com/parcel-bundler/parcel/tree/fix-html-bug)
parcel build ./*.html
a.html
<head>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<script src="./index.js"></script>
</body>
b.html
<head>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<script src="./index.js"></script>
</body>
index.js
import "./style.css";
index.css
html, body {}
| Software | Version(s) |
| ---------------- | ---------- |
| Parcel | v2.0.0-beta.1
which is a good solution for this specific use-case as it should really only be referenced once.
I think @devongovett's plan to make all bundles in an HTML file part of a single bundle group could deduplicate the stylesheet.
Sounds like a good way to solve this particular issue and was also leaning towards deduplicating it in some way but couldn't really figure it out right away and was/am worried that it would not really solve it entirely.
Shouldn't replaceURLReferences always return the bundle that resulted from the dependency? Maybe we should figure out a way to link them instead of just taking the last bundle in the bundle_group? The css bundle has no connection to the js dependency that it replaced in the html, so that seems like it should not happen whether we de-duplicate or not
(https://github.com/parcel-bundler/parcel/issues/3898)
Maybe we should figure out a way to link them instead of just taking the last bundle in the bundle_group
BundleGroups have an entryAssetId, I think it should use the bundle which has that asset as an entry?
@mischnic wow I'll try out if that could actually solve this issue, looking positive so far.
Edit: That actually fixed it, opened a PR
Haha I'm literally working on moving dependencies in HTML into the same bundle group right now, and also came across this issue. ๐
Most helpful comment
Haha I'm literally working on moving dependencies in HTML into the same bundle group right now, and also came across this issue. ๐