vite-plugin-fonts
Advanced tools
Comparing version
@@ -1,9 +0,9 @@ | ||
import { HtmlTagDescriptor } from 'vite'; | ||
import { Plugin } from 'vite'; | ||
declare type GoogleFontFamily = { | ||
interface GoogleFontFamily { | ||
name: string; | ||
styles?: string; | ||
defer?: boolean; | ||
}; | ||
declare type GoogleFonts = { | ||
} | ||
interface GoogleFonts { | ||
families: (string | GoogleFontFamily)[]; | ||
@@ -13,19 +13,71 @@ text?: string; | ||
preconnect?: boolean; | ||
}; | ||
} | ||
declare type TypeKitFonts = { | ||
interface TypeKitFonts { | ||
id: string; | ||
defer?: boolean; | ||
}; | ||
} | ||
declare type VitePluginFontsOptions = { | ||
interface CustomFontFamily { | ||
/** | ||
* Name of the font family. | ||
* @example 'Comic Sans MS' | ||
*/ | ||
name: string; | ||
/** | ||
* Regex(es) of font files to import. The names of the files will | ||
* predicate the `font-style` and `font-weight` values of the `@font-rule`'s. | ||
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#common_weight_name_mapping | ||
* | ||
* @example | ||
* A value of `./RobotoBoldItalic.*` will create this `@font-rule`: | ||
* | ||
* ```css | ||
* font-face { | ||
* font-family: 'Roboto'; | ||
* src: url(./RobotoBoldItalic.ttf) format('truetype') | ||
* url(./RobotoBoldItalic.woff) format('woff') | ||
* url(./RobotoBoldItalic.woff2) format('woff2'); | ||
* font-weight: bold; | ||
* font-style: italic; | ||
* font-display: auto; | ||
* } | ||
* ``` | ||
*/ | ||
src: string | string[]; | ||
/** | ||
* Local name of the font. Used to add `src: local()` to `@font-rule`. | ||
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face#description | ||
*/ | ||
local?: string | string[]; | ||
} | ||
interface CustomFonts { | ||
/** | ||
* Font families. | ||
*/ | ||
families: CustomFontFamily[] | Record<string, string | string[] | Omit<CustomFontFamily, 'name'>>; | ||
/** | ||
* Defines the default `font-display` value used for the generated | ||
* `@font-rule` classes. | ||
* @see https://developer.mozilla.org/fr/docs/Web/CSS/@font-face/font-display | ||
* @default 'auto' | ||
*/ | ||
display?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional'; | ||
/** | ||
* Using `<link rel="preload">` will trigger a request for the WebFont | ||
* early in the critical rendering path, without having to wait for the | ||
* CSSOM to be created. | ||
* @see https://web.dev/optimize-webfont-loading/#preload-your-webfont-resources | ||
* @default true | ||
*/ | ||
preload?: boolean; | ||
} | ||
interface VitePluginFontsOptions { | ||
google?: GoogleFonts; | ||
typekit?: TypeKitFonts; | ||
}; | ||
declare function VitePluginFonts(options?: VitePluginFontsOptions): { | ||
name: string; | ||
transformIndexHtml(): HtmlTagDescriptor[]; | ||
}; | ||
custom?: CustomFonts; | ||
} | ||
declare function VitePluginFonts(options?: VitePluginFontsOptions): Plugin; | ||
export default VitePluginFonts; | ||
export { VitePluginFonts as Plugin, VitePluginFontsOptions }; | ||
export { VitePluginFonts, VitePluginFontsOptions, VitePluginFonts as default }; |
@@ -1,2 +0,42 @@ | ||
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/google-fonts.ts | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getOwnPropSymbols = Object.getOwnPropertySymbols; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __propIsEnum = Object.prototype.propertyIsEnumerable; | ||
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
var __spreadValues = (a, b) => { | ||
for (var prop in b || (b = {})) | ||
if (__hasOwnProp.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
if (__getOwnPropSymbols) | ||
for (var prop of __getOwnPropSymbols(b)) { | ||
if (__propIsEnum.call(b, prop)) | ||
__defNormalProp(a, prop, b[prop]); | ||
} | ||
return a; | ||
}; | ||
var __export = (target, all) => { | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __copyProps = (to, from, except, desc) => { | ||
if (from && typeof from === "object" || typeof from === "function") { | ||
for (let key of __getOwnPropNames(from)) | ||
if (!__hasOwnProp.call(to, key) && key !== except) | ||
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
} | ||
return to; | ||
}; | ||
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
// src/index.ts | ||
var src_exports = {}; | ||
__export(src_exports, { | ||
VitePluginFonts: () => VitePluginFonts, | ||
default: () => src_default | ||
}); | ||
module.exports = __toCommonJS(src_exports); | ||
// src/google-fonts.ts | ||
var GoogleFontsBase = "https://fonts.googleapis.com/css2"; | ||
@@ -120,13 +160,148 @@ function injectFonts({ | ||
// src/custom.ts | ||
var import_fast_glob = require("fast-glob"); | ||
var resolveWeight = (weightOrSrc) => { | ||
if (typeof weightOrSrc === "number") | ||
return weightOrSrc; | ||
if (!weightOrSrc) | ||
return 400; | ||
weightOrSrc = weightOrSrc.toLowerCase(); | ||
if (weightOrSrc.includes("thin")) | ||
return 100; | ||
if (weightOrSrc.includes("extralight")) | ||
return 200; | ||
if (weightOrSrc.includes("ultralight")) | ||
return 200; | ||
if (weightOrSrc.includes("light")) | ||
return 300; | ||
if (weightOrSrc.includes("normal")) | ||
return 400; | ||
if (weightOrSrc.includes("medium")) | ||
return 500; | ||
if (weightOrSrc.includes("semibold")) | ||
return 600; | ||
if (weightOrSrc.includes("demibold")) | ||
return 600; | ||
if (weightOrSrc.includes("bold")) | ||
return 700; | ||
if (weightOrSrc.includes("extrabold")) | ||
return 800; | ||
if (weightOrSrc.includes("ultrabold")) | ||
return 800; | ||
if (weightOrSrc.includes("black")) | ||
return 900; | ||
if (weightOrSrc.includes("heavy")) | ||
return 900; | ||
return 400; | ||
}; | ||
var resolveStyle = (styleOrSrc) => { | ||
if (!styleOrSrc) | ||
return "normal"; | ||
styleOrSrc = styleOrSrc.toLowerCase(); | ||
if (styleOrSrc.includes("normal")) | ||
return "normal"; | ||
if (styleOrSrc.includes("italic")) | ||
return "italic"; | ||
if (styleOrSrc.includes("oblique")) | ||
return "oblique"; | ||
return "normal"; | ||
}; | ||
var createFontFaceCSS = ({ name, src, local, weight, style, display }) => { | ||
const srcs = (Array.isArray(src) ? src : [src]).filter(Boolean).map((url) => { | ||
let format = url.split(".").pop(); | ||
if (format === "ttf") | ||
format = "truetype"; | ||
return `url('${url}') format('${format}')`; | ||
}).join(",\n "); | ||
const locals = (Array.isArray(local) ? local : [local]).filter(Boolean).map((x) => `local('${x}')`).join(", "); | ||
return `@font-face { | ||
font-family: '${name}'; | ||
src: ${[srcs, locals].filter(Boolean).join(",")}; | ||
font-weight: ${weight}; | ||
font-style: ${style}; | ||
font-display: ${display}; | ||
}`; | ||
}; | ||
var createFontFaceLink = (href) => { | ||
return { | ||
tag: "link", | ||
attrs: { | ||
rel: "preload", | ||
as: "font", | ||
type: `font/${href.split(".").pop()}`, | ||
href, | ||
crossorigin: true | ||
} | ||
}; | ||
}; | ||
var custom_default = (options, config2) => { | ||
const tags = []; | ||
const css = []; | ||
let { | ||
families = [], | ||
display = "auto", | ||
preload = true | ||
} = options; | ||
if (!Array.isArray(families)) { | ||
families = Object.entries(families).map(([name, family]) => Array.isArray(family) || typeof family === "string" ? { name, src: family } : __spreadValues({ name }, family)); | ||
} | ||
for (const { name, src, local } of families) { | ||
const facesGrouped = {}; | ||
(Array.isArray(src) ? src : [src]).flatMap((x) => (0, import_fast_glob.sync)(x, { absolute: true, cwd: config2.root, onlyFiles: true })).filter(Boolean).forEach((src2) => { | ||
var _a, _b; | ||
const srcNoExt = (_a = src2.match(/(.*)\.(\w|\d)+$/)) == null ? void 0 : _a[1].toLowerCase(); | ||
if (srcNoExt) | ||
facesGrouped[srcNoExt] = ((_b = facesGrouped[srcNoExt]) != null ? _b : []).concat(src2); | ||
}); | ||
const faces = Object.entries(facesGrouped).map(([srcNoExt, src2]) => ({ | ||
name, | ||
src: src2, | ||
weight: resolveWeight(srcNoExt), | ||
style: resolveStyle(srcNoExt), | ||
display, | ||
local | ||
})); | ||
const hrefs = faces.flatMap((face) => face.src).map((src2) => src2.replace(config2.root, ".")); | ||
if (preload) | ||
tags.push(...hrefs.map(createFontFaceLink)); | ||
for (const face of faces) | ||
css.push(createFontFaceCSS(face)); | ||
} | ||
return { | ||
tags, | ||
css: css.join("\n\n") | ||
}; | ||
}; | ||
// src/index.ts | ||
var config; | ||
var MODULE_ID = "virtual:fonts.css"; | ||
var MODULE_ID_RESOLVED = "/@vite-plugin-fonts/fonts.css"; | ||
function VitePluginFonts(options = {}) { | ||
return { | ||
name: "vite-plugin-fonts", | ||
transformIndexHtml() { | ||
const tags = []; | ||
if (options.typekit) | ||
tags.push(...typekit_default(options.typekit)); | ||
if (options.google) | ||
tags.push(...google_fonts_default(options.google)); | ||
return tags; | ||
enforce: "pre", | ||
configResolved(_config) { | ||
config = _config; | ||
}, | ||
transformIndexHtml: { | ||
enforce: "pre", | ||
transform: () => { | ||
const tags = []; | ||
if (options.typekit) | ||
tags.push(...typekit_default(options.typekit)); | ||
if (options.google) | ||
tags.push(...google_fonts_default(options.google)); | ||
if (options.custom) | ||
tags.push(...custom_default(options.custom, config).tags); | ||
return tags; | ||
} | ||
}, | ||
resolveId(id) { | ||
if (id === MODULE_ID) | ||
return MODULE_ID_RESOLVED; | ||
}, | ||
load(id) { | ||
if (id === MODULE_ID_RESOLVED) | ||
return options.custom ? custom_default(options.custom, config).css : ""; | ||
} | ||
@@ -136,5 +311,5 @@ }; | ||
var src_default = VitePluginFonts; | ||
exports.Plugin = VitePluginFonts; exports.default = src_default; | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
VitePluginFonts | ||
}); |
{ | ||
"name": "vite-plugin-fonts", | ||
"version": "0.2.2", | ||
"version": "0.3.0", | ||
"description": "Webfont loader for vite", | ||
@@ -18,2 +18,3 @@ "author": "stafyniaksacha", | ||
"example:build": "npm -C example run build", | ||
"example:preview": "npm -C example run preview", | ||
"build": "tsup src/index.ts --dts --format cjs,esm", | ||
@@ -27,10 +28,13 @@ "lint": "eslint --ext .ts ./src", | ||
"devDependencies": { | ||
"@antfu/eslint-config-ts": "^0.5.0", | ||
"@typescript-eslint/eslint-plugin": "^4.17.0", | ||
"eslint": "^7.22.0", | ||
"@antfu/eslint-config-ts": "^0.18.8", | ||
"@typescript-eslint/eslint-plugin": "^5.15.0", | ||
"eslint": "^8.11.0", | ||
"eslint-plugin-eslint-comments": "^3.2.0", | ||
"tsup": "^4.6.1", | ||
"typescript": "^4.2.3", | ||
"vite": "^2.0.5" | ||
"tsup": "^5.12.1", | ||
"typescript": "^4.6.2", | ||
"vite": "^2.8.6" | ||
}, | ||
"dependencies": { | ||
"fast-glob": "^3.2.11" | ||
} | ||
} |
@@ -28,2 +28,8 @@ # vite-plugin-fonts | ||
### Import generated `@font-rules` CSS | ||
Only needed if using local/custom fonts | ||
```ts | ||
// main.ts | ||
import 'virtual:fonts.css' | ||
``` | ||
@@ -104,2 +110,37 @@ ## Options | ||
}, | ||
// Custom fonts. | ||
custom: { | ||
/** | ||
* Fonts families lists | ||
*/ | ||
families: [{ | ||
/** | ||
* Name of the font family. | ||
*/ | ||
name: 'Roboto', | ||
/** | ||
* Local name of the font. Used to add `src: local()` to `@font-rule`. | ||
*/ | ||
local: 'Roboto', | ||
/** | ||
* Regex(es) of font files to import. The names of the files will | ||
* predicate the `font-style` and `font-weight` values of the `@font-rule`'s. | ||
*/ | ||
src: './src/assets/fonts/*.ttf', | ||
}], | ||
/** | ||
* Defines the default `font-display` value used for the generated | ||
* `@font-rule` classes. | ||
*/ | ||
display: 'auto', | ||
/** | ||
* Using `<link rel="preload">` will trigger a request for the WebFont | ||
* early in the critical rendering path, without having to wait for the | ||
* CSSOM to be created. | ||
*/ | ||
preload: true | ||
} | ||
}) | ||
@@ -106,0 +147,0 @@ ], |
Sorry, the diff of this file is not supported yet
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
23714
129.63%671
127.46%154
36.28%2
100%2
100%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed