Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: webfont plugin #468

Merged
merged 6 commits into from
Mar 27, 2023
Merged

feat: webfont plugin #468

merged 6 commits into from
Mar 27, 2023

Conversation

0xb4lint
Copy link
Contributor

Description

Webfont-DL plugin scans the index.html, downloads the Google Fonts CSS file(s), extracts the font URLs, downloads the fonts, generates an embedded CSS (<style> tag) or a webfont / external CSS file, add them to the bundle and injects the following code into your website's using a non-render blocking method.

The end result of this plugin is a self-hosted webfont.

Additional context

Benchmark (Lighthouse: 94 vs. 100): https://github.com/feat-agency/vite-plugin-webfont-dl#-benchmark

@antfu
Copy link
Member

antfu commented Jan 20, 2023

While I like this idea, it seems not able to capture the webfonts used by UnoCSS?

on build:

image

@0xb4lint
Copy link
Contributor Author

Thanks for the feedback @antfu!

I'll dig deeper into UnoCSS webfont presets and implement the capture mechanism. 😉

@0xb4lint
Copy link
Contributor Author

0xb4lint commented Jan 26, 2023

Hi @antfu!

I've just released the v3.5.0-beta.0 version of vite-plugin-webfont-dl.
Could you please check it and share your thoughts about adding this way as a Vitesse dependency?

I've implemented a new collection or capture mechanism for @import() rule and @font-face definitions. In the generateBundle hook the plugin will search for generated css files and scans their content.



Without vite-plugin-webfont-dl bundle example (currently only with .ttf files, but there's unocss/unocss#2114 for the rescue 😉):

dist/assets/index-xxxxxxxx.css (having @font-face definitions, with Google URLs):

*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}@font-face{font-family:Fira Code;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/firacode/v21/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sFVc.ttf) format("truetype")}@font-face{font-family:Fira Mono;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/firamono/v14/N0bX2SlFPv1weGeLZDtQIQ.ttf) format("truetype")}@font-face{font-family:Fira Mono;font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/firamono/v14/N0bS2SlFPv1weGeLZDtondv3mQ.ttf) format("truetype")}@font-face{font-family:Lato;font-style:italic;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v23/S6u8w4BMUTPHjxswWw.ttf) format("truetype")}@font-face{font-family:Lato;font-style:italic;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v23/S6u_w4BMUTPHjxsI5wqPHA.ttf) format("truetype")}@font-face{font-family:Lato;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v23/S6uyw4BMUTPHvxk.ttf) format("truetype")}@font-face{font-family:Lato;font-style:normal;font-weight:700;font-display:swap;src:url(https://fonts.gstatic.com/s/lato/v23/S6u9w4BMUTPHh6UVew8.ttf) format("truetype")}@font-face{font-family:Lobster;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/lobster/v28/neILzCirqoswsqX9_oU.ttf) format("truetype")}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(https://fonts.gstatic.com/s/roboto/v30/KFOmCnqEu92Fr1Me5Q.ttf) format("truetype")}


With vite-plugin-webfont-dl bundle example:

dist/assets/index-xxxxxxxx.css (there's no @font-face definition):

*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}

dist/index.html (@font-face definitions with local urls):

<style>@font-face{font-family:Fira Code;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sFVc-01bd31d7.ttf) format("truetype")}@font-face{font-family:Fira Mono;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/N0bX2SlFPv1weGeLZDtQIQ-da844d7e.ttf) format("truetype")}@font-face{font-family:Fira Mono;font-style:normal;font-weight:700;font-display:swap;src:url(/assets/N0bS2SlFPv1weGeLZDtondv3mQ-dafd0b27.ttf) format("truetype")}@font-face{font-family:Lato;font-style:italic;font-weight:400;font-display:swap;src:url(/assets/S6u8w4BMUTPHjxswWw-ae2f4abf.ttf) format("truetype")}@font-face{font-family:Lato;font-style:italic;font-weight:700;font-display:swap;src:url(/assets/S6u_w4BMUTPHjxsI5wqPHA-0c55b8d3.ttf) format("truetype")}@font-face{font-family:Lato;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/S6uyw4BMUTPHvxk-f43f1c77.ttf) format("truetype")}@font-face{font-family:Lato;font-style:normal;font-weight:700;font-display:swap;src:url(/assets/S6u9w4BMUTPHh6UVew8-02e8f4be.ttf) format("truetype")}@font-face{font-family:Lobster;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/neILzCirqoswsqX9_oU-dfdc2254.ttf) format("truetype")}@font-face{font-family:Roboto;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/KFOmCnqEu92Fr1Me5Q-7277cfb8.ttf) format("truetype")}</style>

@0xb4lint 0xb4lint marked this pull request as draft January 26, 2023 16:35
@0xb4lint
Copy link
Contributor Author

@antfu I've just released vite-plugin-webfont-dl plugin's v3.5.0.
The @font-face capture mechanism is ready to use. 😉

@0xb4lint 0xb4lint marked this pull request as ready for review January 27, 2023 13:51
@antfu antfu merged commit 9071f05 into antfu-collective:main Mar 27, 2023
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants