From 8b0da1d674921c0e7354315bc3155e7aceeb23fc Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Wed, 22 Jun 2022 22:19:37 -0400 Subject: [PATCH] fix #2337: add support for font file MIME types --- CHANGELOG.md | 13 +++ internal/bundler/bundler_loader_test.go | 80 +++++++++++++++++ .../bundler/snapshots/snapshots_default.txt | 89 +++++++++++++++++++ internal/helpers/mime.go | 25 ++++-- 4 files changed, 201 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 199fe20c546..32feda31a22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## Unreleased + +* Add support for font file MIME types ([#2337](https://github.com/evanw/esbuild/issues/2337)) + + This release adds support for font file MIME types to esbuild, which means they are now recognized by the built-in local web server and they are now used when a font file is loaded using the `dataurl` loader. The full set of newly-added file extension MIME type mappings is as follows: + + * `.eot` => `application/vnd.ms-fontobject` + * `.otf` => `font/otf` + * `.sfnt` => `font/sfnt` + * `.ttf` => `font/ttf` + * `.woff` => `font/woff` + * `.woff2` => `font/woff2` + ## 0.14.47 * Make global names more compact when `||=` is available ([#2331](https://github.com/evanw/esbuild/issues/2331)) diff --git a/internal/bundler/bundler_loader_test.go b/internal/bundler/bundler_loader_test.go index ff51f0e11c7..3171d48d72f 100644 --- a/internal/bundler/bundler_loader_test.go +++ b/internal/bundler/bundler_loader_test.go @@ -960,6 +960,86 @@ func TestLoaderDataURLUnknownMIME(t *testing.T) { }) } +func TestLoaderDataURLExtensionBasedMIME(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.foo": ` + export { default as css } from "./example.css" + export { default as eot } from "./example.eot" + export { default as gif } from "./example.gif" + export { default as htm } from "./example.htm" + export { default as html } from "./example.html" + export { default as jpeg } from "./example.jpeg" + export { default as jpg } from "./example.jpg" + export { default as js } from "./example.js" + export { default as json } from "./example.json" + export { default as mjs } from "./example.mjs" + export { default as otf } from "./example.otf" + export { default as pdf } from "./example.pdf" + export { default as png } from "./example.png" + export { default as sfnt } from "./example.sfnt" + export { default as svg } from "./example.svg" + export { default as ttf } from "./example.ttf" + export { default as wasm } from "./example.wasm" + export { default as webp } from "./example.webp" + export { default as woff } from "./example.woff" + export { default as woff2 } from "./example.woff2" + export { default as xml } from "./example.xml" + `, + "/example.css": `css`, + "/example.eot": `eot`, + "/example.gif": `gif`, + "/example.htm": `htm`, + "/example.html": `html`, + "/example.jpeg": `jpeg`, + "/example.jpg": `jpg`, + "/example.js": `js`, + "/example.json": `json`, + "/example.mjs": `mjs`, + "/example.otf": `otf`, + "/example.pdf": `pdf`, + "/example.png": `png`, + "/example.sfnt": `sfnt`, + "/example.svg": `svg`, + "/example.ttf": `ttf`, + "/example.wasm": `wasm`, + "/example.webp": `webp`, + "/example.woff": `woff`, + "/example.woff2": `woff2`, + "/example.xml": `xml`, + }, + entryPaths: []string{"/entry.foo"}, + options: config.Options{ + Mode: config.ModeBundle, + AbsOutputDir: "/out", + ExtensionToLoader: map[string]config.Loader{ + ".foo": config.LoaderJS, + ".css": config.LoaderDataURL, + ".eot": config.LoaderDataURL, + ".gif": config.LoaderDataURL, + ".htm": config.LoaderDataURL, + ".html": config.LoaderDataURL, + ".jpeg": config.LoaderDataURL, + ".jpg": config.LoaderDataURL, + ".js": config.LoaderDataURL, + ".json": config.LoaderDataURL, + ".mjs": config.LoaderDataURL, + ".otf": config.LoaderDataURL, + ".pdf": config.LoaderDataURL, + ".png": config.LoaderDataURL, + ".sfnt": config.LoaderDataURL, + ".svg": config.LoaderDataURL, + ".ttf": config.LoaderDataURL, + ".wasm": config.LoaderDataURL, + ".webp": config.LoaderDataURL, + ".woff": config.LoaderDataURL, + ".woff2": config.LoaderDataURL, + ".xml": config.LoaderDataURL, + }, + }, + }) +} + func TestLoaderCopyWithBundleFromJS(t *testing.T) { default_suite.expectBundled(t, bundled{ files: map[string]string{ diff --git a/internal/bundler/snapshots/snapshots_default.txt b/internal/bundler/snapshots/snapshots_default.txt index 9635e700c1e..caa936a5adc 100644 --- a/internal/bundler/snapshots/snapshots_default.txt +++ b/internal/bundler/snapshots/snapshots_default.txt @@ -1967,6 +1967,95 @@ console.log([ json_charset_UTF_8_base64_eyJ3b3JrcyI6dHJ1ZX0_default ]); +================================================================================ +TestLoaderDataURLExtensionBasedMIME +---------- /out/entry.js ---------- +// example.css +var example_default = "data:text/css;charset=utf-8;base64,Y3Nz"; + +// example.eot +var example_default2 = "data:application/vnd.ms-fontobject;base64,ZW90"; + +// example.gif +var example_default3 = "data:image/gif;base64,Z2lm"; + +// example.htm +var example_default4 = "data:text/html;charset=utf-8;base64,aHRt"; + +// example.html +var example_default5 = "data:text/html;charset=utf-8;base64,aHRtbA=="; + +// example.jpeg +var example_default6 = "data:image/jpeg;base64,anBlZw=="; + +// example.jpg +var example_default7 = "data:image/jpeg;base64,anBn"; + +// example.js +var example_default8 = "data:text/javascript;charset=utf-8;base64,anM="; + +// example.json +var example_default9 = "data:application/json;base64,anNvbg=="; + +// example.mjs +var example_default10 = "data:text/javascript;charset=utf-8;base64,bWpz"; + +// example.otf +var example_default11 = "data:font/otf;base64,b3Rm"; + +// example.pdf +var example_default12 = "data:application/pdf;base64,cGRm"; + +// example.png +var example_default13 = "data:image/png;base64,cG5n"; + +// example.sfnt +var example_default14 = "data:font/sfnt;base64,c2ZudA=="; + +// example.svg +var example_default15 = "data:image/svg+xml;base64,c3Zn"; + +// example.ttf +var example_default16 = "data:font/ttf;base64,dHRm"; + +// example.wasm +var example_default17 = "data:application/wasm;base64,d2FzbQ=="; + +// example.webp +var example_default18 = "data:image/webp;base64,d2VicA=="; + +// example.woff +var example_default19 = "data:font/woff;base64,d29mZg=="; + +// example.woff2 +var example_default20 = "data:font/woff2;base64,d29mZjI="; + +// example.xml +var example_default21 = "data:text/xml;charset=utf-8;base64,eG1s"; +export { + example_default as css, + example_default2 as eot, + example_default3 as gif, + example_default4 as htm, + example_default5 as html, + example_default6 as jpeg, + example_default7 as jpg, + example_default8 as js, + example_default9 as json, + example_default10 as mjs, + example_default11 as otf, + example_default12 as pdf, + example_default13 as png, + example_default14 as sfnt, + example_default15 as svg, + example_default16 as ttf, + example_default17 as wasm, + example_default18 as webp, + example_default19 as woff, + example_default20 as woff2, + example_default21 as xml +}; + ================================================================================ TestLoaderDataURLTextCSS ---------- /out/entry.css ---------- diff --git a/internal/helpers/mime.go b/internal/helpers/mime.go index 5ef8dc52810..9897b373d4f 100644 --- a/internal/helpers/mime.go +++ b/internal/helpers/mime.go @@ -3,21 +3,34 @@ package helpers import "strings" var builtinTypesLower = map[string]string{ + // Text ".css": "text/css; charset=utf-8", - ".gif": "image/gif", ".htm": "text/html; charset=utf-8", ".html": "text/html; charset=utf-8", - ".jpeg": "image/jpeg", - ".jpg": "image/jpeg", ".js": "text/javascript; charset=utf-8", ".json": "application/json", ".mjs": "text/javascript; charset=utf-8", - ".pdf": "application/pdf", + ".xml": "text/xml; charset=utf-8", + + // Images + ".gif": "image/gif", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", ".png": "image/png", ".svg": "image/svg+xml", - ".wasm": "application/wasm", ".webp": "image/webp", - ".xml": "text/xml; charset=utf-8", + + // Fonts + ".eot": "application/vnd.ms-fontobject", + ".otf": "font/otf", + ".sfnt": "font/sfnt", + ".ttf": "font/ttf", + ".woff": "font/woff", + ".woff2": "font/woff2", + + // Other + ".pdf": "application/pdf", + ".wasm": "application/wasm", } // This is used instead of Go's built-in "mime.TypeByExtension" function because