Repository navigation
fix(webpack): keep binary files intact in the load and transform loaders - #623
Conversation
Both loaders were regular loaders, so webpack decoded every file they ran on as UTF-8 text before handing it over. A binary file that the hook did not handle (an image or a font) was passed on as that decoded string and came out corrupted. Mark them as raw loaders so the source arrives as a Buffer and is passed on unchanged, and give the transform hook a string. Fixes unjs#524
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
commit: |
Fixes #524.
Both webpack loaders (
loadandtransform) were regular loaders. webpack decodes the source as UTF-8 text before it gives it to a non raw loader, so for a binary file the loader got a corrupted string, and when the hook did not handle the file the loader passed that string on. Anything that is not valid UTF-8 (images, fonts) ended up broken, which is what happens in the reproduction with the vue-i18n plugin: itsloadhook returns nothing for those files, so unplugin handed back the damaged source.The fix marks both loaders with
export const raw = true(see https://webpack.js.org/api/loaders/#raw-loader), so the source arrives as a Buffer and the fallback paths pass the original Buffer on unchanged. webpack converts it back to a string for the next loader if that one is not raw. The one place that needs a string is thetransformhook, so the loader decodes the Buffer to UTF-8 before calling the filter and the handler, which is what the hook got before.I checked this against a real webpack build, not only with unit tests. With a plugin that has a
loadhook and no filter, a project that imports a PNG asasset/resourceemitted a PNG that was different from the source before the change, and a byte for byte identical one after it. I also added unit tests for both loaders (they exportraw, binary input is passed on as the same bytes when the hook does not handle it, and the transform handler still gets a string). Three of them fail without the change. The full vitest run and eslint pass.This does not touch the rspack loaders, which have the same shape (
src/rspack/loaders). I did not want to change them without testing them against rspack, I can look at those as a follow up if you want.Summary by CodeRabbit
Bug Fixes
Tests