@nuxtjs/fontaine
Version:
[![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [![Github Actions][github-actions-src]][github-actions-href] [![Codecov][codecov-src]][codecov-href]
136 lines (129 loc) • 4.81 kB
JavaScript
;
const node_url = require('node:url');
const node_path = require('node:path');
const kit = require('@nuxt/kit');
const pathe = require('pathe');
const ufo = require('ufo');
const fontaine = require('fontaine');
const MagicString = require('magic-string');
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
const NitroTransformPlugin = (options) => ({
name: "nuxt-fontaine-transform-nitro",
transform(code, source) {
if (!code.includes("__INLINED_CSS__")) return;
const s = new MagicString__default(code);
s.replace("__INLINED_CSS__", `\` ${options.cssContext.value.replace(/\s+/g, " ")}\``);
return {
code: s.toString(),
map: options.sourcemap ? s.generateMap({ source, includeContent: true }) : void 0
};
}
});
const module$1 = kit.defineNuxtModule({
meta: {
configKey: "fontMetrics",
name: "@nuxtjs/fontaine",
compatibility: {
nuxt: ">=3.0.0-rc.6 || ^4.0.0"
}
},
defaults: (nuxt) => ({
inject: true,
inline: nuxt.options.ssr,
fallbacks: ["Segoe UI", "Roboto", "Helvetica Neue", "Arial", "Noto Sans"],
fonts: []
}),
async setup(options, nuxt) {
if (nuxt.options._prepare) return;
if (nuxt.options.fontMetrics?.fallbacks) {
options.fallbacks = nuxt.options.fontMetrics?.fallbacks;
}
const logger = kit.useLogger("@nuxtjs/fontaine");
const css = (async () => {
let css2 = "";
for (const font of options.fonts) {
const {
family,
src,
fallbackName,
fallbacks,
root: fontRoot
} = typeof font === "string" ? { family: font } : font;
let metrics = await fontaine.getMetricsForFamily(family);
if (!metrics && src && !ufo.hasProtocol(src)) {
const file = pathe.resolve(
nuxt.options.srcDir,
fontRoot ?? options.root ?? nuxt.options.dir.public,
src
);
metrics = await fontaine.readMetrics(node_url.pathToFileURL(file));
}
if (!metrics) {
logger.warn("Could not find metrics for font", family);
continue;
}
for (const font2 of fallbacks || options.fallbacks) {
css2 += fontaine.generateFontFace(metrics, {
name: fallbackName || fontaine.generateFallbackName(family),
font: font2,
metrics: await fontaine.getMetricsForFamily(font2)
});
}
}
return css2;
})();
const cssContext = { value: "" };
if (options.inject) {
const resolvePath = (id) => {
if (ufo.hasProtocol(id)) return id;
if (node_path.isAbsolute(id))
return node_url.pathToFileURL(pathe.resolve(nuxt.options.srcDir, nuxt.options.dir.public, ufo.withoutLeadingSlash(id)));
return node_url.pathToFileURL(kit.resolveAlias(id));
};
const transformOptions = {
fallbacks: options.fallbacks,
resolvePath,
css: cssContext,
skipFontFaceGeneration: (fallbackName) => {
return options.inline && options.fonts.some((font) => {
const previouslyGeneratedFallbackName = typeof font === "string" ? fontaine.generateFallbackName(font) : font.fallbackName || fontaine.generateFallbackName(font.family);
return previouslyGeneratedFallbackName === fallbackName;
});
},
sourcemap: !!nuxt.options.sourcemap.client
};
kit.addVitePlugin(fontaine.FontaineTransform.vite(transformOptions), { server: false });
kit.addWebpackPlugin(fontaine.FontaineTransform.webpack(transformOptions), { server: false });
nuxt.hook("nitro:config", async (config) => {
const plugins = await config.rollupConfig.plugins;
if (!plugins || !Array.isArray(plugins)) return;
plugins.push(
NitroTransformPlugin({
sourcemap: true,
cssContext
})
);
});
}
if (options.inline) {
kit.addPluginTemplate({
filename: "font-fallback-inlining-plugin.server.ts",
getContents: async () => [
`import { defineNuxtPlugin, useHead } from '#imports'`,
`const css = \`${(await css).replace(/\s+/g, " ")}\``,
`export default defineNuxtPlugin(() => { useHead({ style: [{ innerHTML: css ${!nuxt.options.dev && options.inject ? "+ __INLINED_CSS__ " : ""}}] }) })`
].join("\n"),
mode: "server"
});
} else {
kit.addTemplate({
filename: "font-fallbacks.css",
write: true,
getContents: () => css
});
nuxt.options.css.push("#build/font-fallbacks.css");
}
}
});
module.exports = module$1;