UNPKG

vite-font-unicode-range

Version:

[![npm version](https://img.shields.io/npm/v/vite-font-unicode-range)](https://www.npmjs.com/package/vite-font-unicode-range) [![license](https://img.shields.io/npm/l/vite-font-unicode-range)](https://github.com/yourusername/vite-font-unicode-range/blob/m

6 lines (4 loc) 2.86 kB
"use strict";const C=require("vite"),E=require("css-tree"),b=require("subset-font"),k=require("path"),m=require("fs"),w=[];function P(t={}){const{include:n=/\.(css|scss|sass|less|styl|stylus)$/,exclude:a,fontExtensions:e=/\.(woff2?|ttf|eot|otf)$/i}=t,r=C.createFilter(n,a),o=new Map;let i="",F=[];const S=new Set;return{name:"vite-plugin-font-unicode-range",enforce:"pre",apply:"build",configResolved(s){i=s.cacheDir,F=s.resolve.alias},generateBundle(){if(!w.length)return;const s=Math.max(...w.map(({fileName:c})=>c.length));console.log(` ✨ [vite-plugin-font-unicode-range] - optimized: `+w.map(({fileName:c,rate:x})=>`\x1B[34m${c.padEnd(s+4)}\x1B[0m\x1B[90m-${x}\x1B[0m`).join(` `))},async resolveId(s){if(S.has(s)||!r(s)||/node_modules/.test(s))return;S.add(s);const c=await this.resolve(s);if(!c)return;s=c.id;const x=await m.promises.readFile(s,"utf8");try{const y=E.parse(x);await Promise.all(y.children.map(async l=>{if(l.type==="Atrule"&&l.name==="font-face"){const U=$(l,"font-family"),A=$(l,"src"),B=$(l,"unicode-range");if(!U||!A||!B)return;const D=j(B);if(D.length===0)return;await Promise.all(R(A).map(async f=>{if(e.test(f)&&!F.find(u=>u.find===f)){const u=await this.resolve(f);if(!u)return;const d=N(f);let p=o.get(d);if(!p){const g=await m.promises.readFile(u.id),q=T(u.id),h=await b(g,M(D),{targetFormat:q}),z=100-h.length*100/g.length;m.existsSync(i)||await m.promises.mkdir(i);const v=`${i}/subset-${d}`;h.length<g.length?(p=v,await m.promises.writeFile(v,h),o.set(d,v),w.push({fileName:d,rate:`${z.toFixed(0)}%`.padEnd(8)+`${I(g.length)}${I(h.length)}`})):p="skip"}p!=="skip"&&F.push({find:f,replacement:p})}}))}}))}catch(y){console.error("Error analyzing CSS:",y)}}}}function I(t){return(t/1024).toFixed(1)+"KB"}function R(t){return t.split(",").map(n=>n.trim())}function M(t){const n=[];return t.forEach(({start:a,end:e})=>{for(let r=a;r<=e;r++)n.push(r)}),String.fromCharCode(...new Set(n))}function N(t){return(t.split("/").pop()||"").replace(/\..*?([a-z]+\d?)$/,".$1")}function $(t,n){const a=Array.from(t.block?.children||[]).find(e=>e.type==="Declaration"&&e.property===n);return a&&Array.from(a.value?.children||[]).filter(e=>e.value).map(e=>e.value).join(" ")||null}function j(t){const n=[],a=t.split(/\s*,\s*/);for(const e of a)if(e.includes("?")){const r=e.match(/U\+([0-9A-Fa-f?]+)/)?.[1]||"",o=parseInt(r.replace(/\?/g,"0"),16),i=parseInt(r.replace(/\?/g,"F"),16);n.push({start:o,end:i})}else if(e.includes("-")){const r=e.match(/U\+([0-9A-Fa-f]+)-([0-9A-Fa-f]+)/);r&&n.push({start:parseInt(r[1],16),end:parseInt(r[2],16)})}else{const r=e.match(/U\+([0-9A-Fa-f]+)/)?.[1]||"0",o=parseInt(r,16);n.push({start:o,end:o})}return n}function T(t){switch(k.extname(t).toLowerCase()){case".woff":return"woff";case".woff2":return"woff2";case".sfnt":return"sfnt";case".ttf":return"truetype";default:return"woff2"}}module.exports=P;