Merge pull request #15155 from webpack/fix-handle-data-uri-in-loader

fix: handle content from loaders
This commit is contained in:
Tobias Koppers 2022-01-17 17:50:19 +01:00 committed by GitHub
commit 1e3e671cfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 22 deletions

View File

@ -74,6 +74,41 @@ const mergeRelatedInfo = (a, b) => {
return result;
};
const encodeDataUri = (encoding, source) => {
let encodedContent;
switch (encoding) {
case "base64": {
encodedContent = source.buffer().toString("base64");
break;
}
case false: {
const content = source.source();
if (typeof content !== "string") {
encodedContent = content.toString("utf-8");
}
encodedContent = encodeURIComponent(encodedContent).replace(
/[!'()*]/g,
character => "%" + character.codePointAt(0).toString(16)
);
break;
}
default:
throw new Error(`Unsupported encoding '${encoding}'`);
}
return encodedContent;
};
const decodeDataUriContent = (encoding, content) => {
const isBase64 = encoding === "base64";
return isBase64
? Buffer.from(content, "base64")
: Buffer.from(decodeURIComponent(content), "ascii");
};
const JS_TYPES = new Set(["javascript"]);
const JS_AND_ASSET_TYPES = new Set(["javascript", "asset"]);
@ -158,33 +193,18 @@ class AssetGenerator extends Generator {
}
let encodedContent;
if (
module.resourceResolveData &&
module.resourceResolveData.encoding === encoding
module.resourceResolveData.encoding === encoding &&
decodeDataUriContent(
module.resourceResolveData.encoding,
module.resourceResolveData.encodedContent
).equals(originalSource.buffer())
) {
encodedContent = module.resourceResolveData.encodedContent;
} else {
switch (encoding) {
case "base64": {
encodedContent = originalSource.buffer().toString("base64");
break;
}
case false: {
const content = originalSource.source();
if (typeof content !== "string") {
encodedContent = content.toString("utf-8");
}
encodedContent = encodeURIComponent(encodedContent).replace(
/[!'()*]/g,
character => "%" + character.codePointAt(0).toString(16)
);
break;
}
default:
throw new Error(`Unsupported encoding '${encoding}'`);
}
encodedContent = encodeDataUri(encoding, originalSource);
}
encodedSource = `data:${mimeType}${

View File

@ -5,6 +5,15 @@ import dataSvg from "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53M
const urlSvg = new URL(
"data:image/svg;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2MDAgNjAwIj48dGl0bGU+aWNvbi1zcXVhcmUtc21hbGw8L3RpdGxlPjxwYXRoIGZpbGw9IiNGRkYiIGQ9Ik0zMDAgLjFMNTY1IDE1MHYyOTkuOUwzMDAgNTk5LjggMzUgNDQ5LjlWMTUweiIvPjxwYXRoIGZpbGw9IiM4RUQ2RkIiIGQ9Ik01MTcuNyA0MzkuNUwzMDguOCA1NTcuOHYtOTJMNDM5IDM5NC4xbDc4LjcgNDUuNHptMTQuMy0xMi45VjE3OS40bC03Ni40IDQ0LjF2MTU5bDc2LjQgNDQuMXpNODEuNSA0MzkuNWwyMDguOSAxMTguMnYtOTJsLTEzMC4yLTcxLjYtNzguNyA0NS40em0tMTQuMy0xMi45VjE3OS40bDc2LjQgNDQuMXYxNTlsLTc2LjQgNDQuMXptOC45LTI2My4yTDI5MC40IDQyLjJ2ODlsLTEzNy4zIDc1LjUtMS4xLjYtNzUuOS00My45em00NDYuOSAwTDMwOC44IDQyLjJ2ODlMNDQ2IDIwNi44bDEuMS42IDc1LjktNDR6Ii8+PHBhdGggZmlsbD0iIzFDNzhDMCIgZD0iTTI5MC40IDQ0NC44TDE2MiAzNzQuMVYyMzQuMmwxMjguNCA3NC4xdjEzNi41em0xOC40IDBsMTI4LjQtNzAuNnYtMTQwbC0xMjguNCA3NC4xdjEzNi41ek0yOTkuNiAzMDN6bS0xMjktODVsMTI5LTcwLjlMNDI4LjUgMjE4bC0xMjguOSA3NC40LTEyOS03NC40eiIvPjwvc3ZnPgo="
);
const urlSvg2 = new URL(
"data:image/svg+xml;p=1;q=2,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke=\"%23343a40\" stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e",
import.meta.url
);
const helloWorld = new URL("data:text/plain,Hello", import.meta.url);
const helloWorldBase64 = new URL(
"data:text/plain;base64,SGVsbG8=",
import.meta.url
);
it("should generate various data-url types", () => {
expect(png).toContain("data:image/png;base64,");
@ -12,4 +21,11 @@ it("should generate various data-url types", () => {
expect(jpg).toContain("data:image/jpeg;base64,");
expect(dataSvg).toContain("data:image/svg+xml;base64,");
expect(urlSvg.href).toContain("data:image/svg;base64,");
expect(urlSvg2.href).toContain(
"data:image/svg+xml;p=1;q=2,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke=\"%23343a40\" stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"
);
expect(helloWorld.href).toContain("data:text/plain,Hello%2C%20World%21");
expect(helloWorldBase64.href).toContain(
"data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="
);
});

View File

@ -0,0 +1,4 @@
/** @type {import("../../../../").LoaderDefinition<{ f(): any }>} */
module.exports = function (source) {
return `${source}, World!`;
};

View File

@ -19,6 +19,11 @@ module.exports = {
maxSize: Infinity
}
}
},
{
mimetype: "text/plain",
type: "asset/inline",
loader: "./loader"
}
]
}