This commit is contained in:
Kismet Hasanaj
2026-05-02 20:07:02 +02:00
parent ce8672e283
commit 34dc9aec52
9428 changed files with 1733330 additions and 0 deletions
@@ -0,0 +1 @@
export default function nextFontLoader(this: any): Promise<any>;
+133
View File
@@ -0,0 +1,133 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return nextFontLoader;
}
});
const _path = /*#__PURE__*/ _interop_require_default(require("path"));
const _picocolors = require("../../../../lib/picocolors");
const _loaderutils3 = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/loader-utils3"));
const _postcssnextfont = /*#__PURE__*/ _interop_require_default(require("./postcss-next-font"));
const _util = require("util");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
async function nextFontLoader() {
const nextFontLoaderSpan = this.currentTraceSpan.traceChild('next-font-loader');
return nextFontLoaderSpan.traceAsyncFn(async ()=>{
const callback = this.async();
/**
* The next-swc plugin next-transform-font turns font function calls into CSS imports.
* At the end of the import, it adds the call arguments and some additional data as a resourceQuery.
* e.g:
* const inter = Inter({ subset: ['latin'] })
* ->
* import inter from 'next/font/google/target.css?{"import":"Inter","subsets":["latin"]}'
*
* Here we parse the resourceQuery to get the font function name, call arguments, and the path to the file that called the font function.
*/ const { path: relativeFilePathFromRoot, import: functionName, arguments: data, variableName } = JSON.parse(this.resourceQuery.slice(1));
// Throw error if @next/font is used in _document.js
if (/pages[\\/]_document\./.test(relativeFilePathFromRoot)) {
const err = Object.defineProperty(new Error(`${(0, _picocolors.bold)('Cannot')} be used within ${(0, _picocolors.cyan)('pages/_document.js')}.`), "__NEXT_ERROR_CODE", {
value: "E135",
enumerable: false,
configurable: true
});
err.name = 'NextFontError';
if (process.env.NEXT_RSPACK) {
// Rspack uses miette for error formatting, which automatically includes stack
// traces in the error message. To avoid showing redundant stack information
// in the final error output, we clear the stack property.
err.stack = undefined;
}
callback(err);
return;
}
const { isDev, isServer, assetPrefix, deploymentId, fontLoaderPath, postcss: getPostcss } = this.getOptions();
if (assetPrefix && !/^\/|https?:\/\//.test(assetPrefix)) {
const err = Object.defineProperty(new Error('assetPrefix must start with a leading slash or be an absolute URL(http:// or https://)'), "__NEXT_ERROR_CODE", {
value: "E72",
enumerable: false,
configurable: true
});
err.name = 'NextFontError';
callback(err);
return;
}
/**
* Emit font files to .next/static/media as [hash].[ext].
*
* If the font should be preloaded, add .p to the filename: [hash].p.[ext]
* NextFontManifestPlugin adds these files to the next/font manifest.
*
* If the font is using a size-adjust fallback font, add -s to the filename: [hash]-s.[ext]
* NextFontManifestPlugin uses this to see if fallback fonts are being used.
* This is used to collect stats on fallback fonts usage by the Google Aurora team.
*/ const emitFontFile = (content, ext, preload, isUsingSizeAdjust)=>{
const opts = {
context: this.rootContext,
content
};
const interpolatedName = _loaderutils3.default.interpolateName(this, `static/media/[hash]${isUsingSizeAdjust ? '-s' : ''}${preload ? '.p' : ''}.${ext}`, opts);
const outputPath = `${assetPrefix}/_next/${interpolatedName}${deploymentId ? `?dpl=${deploymentId}` : ''}`;
// Only the client emits the font file
if (!isServer) {
this.emitFile(interpolatedName, content, null);
}
// But both the server and client must get the resulting path
return outputPath;
};
try {
// Import the font loader function from either next/font/local or next/font/google
// The font loader function emits font files and returns @font-faces and fallback font metrics
const fontLoader = require(fontLoaderPath).default;
let { css, fallbackFonts, adjustFontFallback, weight, style, variable } = await nextFontLoaderSpan.traceChild('font-loader').traceAsyncFn(()=>fontLoader({
functionName,
variableName,
data,
emitFontFile,
resolve: (src)=>(0, _util.promisify)(this.resolve)(_path.default.dirname(_path.default.join(this.rootContext, relativeFilePathFromRoot)), src.startsWith('.') ? src : `./${src}`),
isDev,
isServer,
loaderContext: this
}));
const { postcss } = await getPostcss();
// Exports will be exported as is from css-loader instead of a CSS module export
const exports1 = [];
// Generate a hash from the CSS content. Used to generate classnames
const fontFamilyHash = _loaderutils3.default.getHashDigest(Buffer.from(css), 'sha1', 'hex', 6);
// Add CSS classes, exports and make the font-family locally scoped by turning it unguessable
const result = await nextFontLoaderSpan.traceChild('postcss').traceAsyncFn(()=>postcss((0, _postcssnextfont.default)({
exports: exports1,
fallbackFonts,
weight,
style,
adjustFontFallback,
variable
})).process(css, {
from: undefined
}));
const ast = {
type: 'postcss',
version: result.processor.version,
root: result.root
};
// Return the resulting CSS and send the postcss ast, font exports and the hash to the css-loader in the meta argument.
callback(null, result.css, null, {
exports: exports1,
ast,
fontFamilyHash
});
} catch (err) {
callback(err);
}
});
}
//# sourceMappingURL=index.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,35 @@
import type { AdjustFontFallback } from '../../../../../font';
/**
* The next/font postcss plugin receives the @font-face declarations returned from the next/font loaders.
*
* It hashes the font-family name to make it unguessable, it shouldn't be globally accessible.
* If it were global, we wouldn't be able to tell which pages are using which fonts when generating preload tags.
*
* If the font loader returned fallback metrics, generate a fallback @font-face.
*
* If the font loader returned a variable name, add a CSS class that declares a variable containing the font and fallback fonts.
*
* Lastly, it adds the font-family to the exports object.
* This enables you to access the actual font-family name, not just through the CSS class.
* e.g:
* const inter = Inter({ subsets: ['latin'] })
* inter.style.fontFamily // => '__Inter_123456'
*/
declare const postcssNextFontPlugin: {
({ exports, fallbackFonts, adjustFontFallback, variable, weight, style, }: {
exports: {
name: any;
value: any;
}[];
fallbackFonts?: string[];
adjustFontFallback?: AdjustFontFallback;
variable?: string;
weight?: string;
style?: string;
}): {
postcssPlugin: string;
Once(root: any): void;
};
postcss: boolean;
};
export default postcssNextFontPlugin;
@@ -0,0 +1,169 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
/**
* The next/font postcss plugin receives the @font-face declarations returned from the next/font loaders.
*
* It hashes the font-family name to make it unguessable, it shouldn't be globally accessible.
* If it were global, we wouldn't be able to tell which pages are using which fonts when generating preload tags.
*
* If the font loader returned fallback metrics, generate a fallback @font-face.
*
* If the font loader returned a variable name, add a CSS class that declares a variable containing the font and fallback fonts.
*
* Lastly, it adds the font-family to the exports object.
* This enables you to access the actual font-family name, not just through the CSS class.
* e.g:
* const inter = Inter({ subsets: ['latin'] })
* inter.style.fontFamily // => '__Inter_123456'
*/ const postcssNextFontPlugin = ({ exports: exports1, fallbackFonts = [], adjustFontFallback, variable, weight, style })=>{
return {
postcssPlugin: 'postcss-next-font',
Once (root) {
let fontFamily;
const normalizeFamily = (family)=>{
return family.replace(/['"]/g, '');
};
const formatFamily = (family)=>{
return `'${family}'`;
};
// Hash font-family names
for (const node of root.nodes){
if (node.type === 'atrule' && node.name === 'font-face') {
const familyNode = node.nodes.find((decl)=>decl.prop === 'font-family');
if (!familyNode) {
continue;
}
if (!fontFamily) {
fontFamily = normalizeFamily(familyNode.value);
}
familyNode.value = formatFamily(fontFamily);
}
}
if (!fontFamily) {
throw Object.defineProperty(new Error("Font loaders must return one or more @font-face's"), "__NEXT_ERROR_CODE", {
value: "E428",
enumerable: false,
configurable: true
});
}
// Add fallback @font-face with the provided override values
let adjustFontFallbackFamily;
if (adjustFontFallback) {
adjustFontFallbackFamily = formatFamily(`${fontFamily} Fallback`);
const fallbackFontFace = _postcss.default.atRule({
name: 'font-face'
});
const { fallbackFont, ascentOverride, descentOverride, lineGapOverride, sizeAdjust } = adjustFontFallback;
fallbackFontFace.nodes = [
new _postcss.default.Declaration({
prop: 'font-family',
value: adjustFontFallbackFamily
}),
new _postcss.default.Declaration({
prop: 'src',
value: `local("${fallbackFont}")`
}),
...ascentOverride ? [
new _postcss.default.Declaration({
prop: 'ascent-override',
value: ascentOverride
})
] : [],
...descentOverride ? [
new _postcss.default.Declaration({
prop: 'descent-override',
value: descentOverride
})
] : [],
...lineGapOverride ? [
new _postcss.default.Declaration({
prop: 'line-gap-override',
value: lineGapOverride
})
] : [],
...sizeAdjust ? [
new _postcss.default.Declaration({
prop: 'size-adjust',
value: sizeAdjust
})
] : []
];
root.nodes.push(fallbackFontFace);
}
// Variable fonts can define ranges of values
const isRange = (value)=>value.trim().includes(' ');
// Format the font families to be used in the CSS
const formattedFontFamilies = [
formatFamily(fontFamily),
...adjustFontFallbackFamily ? [
adjustFontFallbackFamily
] : [],
...fallbackFonts
].join(', ');
// Add class with family, weight and style
const classRule = new _postcss.default.Rule({
selector: '.className'
});
classRule.nodes = [
new _postcss.default.Declaration({
prop: 'font-family',
value: formattedFontFamilies
}),
// If the font only has one weight or style, we can set it on the class
...weight && !isRange(weight) ? [
new _postcss.default.Declaration({
prop: 'font-weight',
value: weight
})
] : [],
...style && !isRange(style) ? [
new _postcss.default.Declaration({
prop: 'font-style',
value: style
})
] : []
];
root.nodes.push(classRule);
// Add CSS class that defines a variable with the font families
if (variable) {
const varialbeRule = new _postcss.default.Rule({
selector: '.variable'
});
varialbeRule.nodes = [
new _postcss.default.Declaration({
prop: variable,
value: formattedFontFamilies
})
];
root.nodes.push(varialbeRule);
}
// Export @font-face values as is
exports1.push({
name: 'style',
value: {
fontFamily: formattedFontFamilies,
fontWeight: !Number.isNaN(Number(weight)) ? Number(weight) : undefined,
fontStyle: style && !isRange(style) ? style : undefined
}
});
}
};
};
postcssNextFontPlugin.postcss = true;
const _default = postcssNextFontPlugin;
//# sourceMappingURL=postcss-next-font.js.map
File diff suppressed because one or more lines are too long