UNPKG

minify-font

Version:

A lightweight font subsetting and conversion tool | 轻量级字体裁剪和转换工具

131 lines (124 loc) 4.36 kB
import path from 'node:path' import { minifyFont } from './minify-font.mjs' /** * 一次性创建多种 Web 字体格式(ttf, woff2, woff 等) * * 该函数会并行生成多种字体格式,即使某个格式失败,其他格式也能继续生成。 * 非常适合用于 Web 项目批量生成字体文件。 * * @param {Object} options - 配置选项 * @param {string} options.input - 输入的字体文件路径(支持 ttf, otf, woff, woff2 等格式) * @param {string} options.text - 需要包含的文字内容,只保留这些字符以减小文件体积 * @param {string} [options.outputDir] - 输出目录,默认为输入文件同级目录下的 output 文件夹 * @param {Function} [options.resolveFileName] - 自定义文件名函数 resolveFileName({ basename, ext }) => string * @param {string[]} [options.formats=['woff2', 'woff', 'ttf']] - 要生成的字体格式数组 * @returns {Promise<CreateWebFontsResult>} 生成结果,包含输出目录和每个字体文件的详细信息 * @returns {string} return.outputDir - 输出目录的绝对路径 * @returns {Array<Object>} return.fonts - 生成的字体文件信息数组 * @returns {string} return.fonts[].format - 字体格式(如 'woff2', 'woff', 'ttf') * @returns {string} return.fonts[].path - 字体文件的完整路径 * @returns {boolean} return.fonts[].success - 是否成功生成 * @returns {Error} [return.fonts[].error] - 失败时的错误信息 * @throws {Error} 当 input 参数缺失时抛出错误 * @throws {Error} 当 text 参数缺失时抛出错误 * @throws {Error} 当 formats 不是非空数组时抛出错误 * * @example * // 基本用法:生成默认的三种格式 * const result = await createWebFonts({ * input: './font.ttf', * text: 'Hello, World! 你好世界' * }) * console.log(result.fonts) // [{ format: 'woff2', path: '...', success: true }, ...] * * @example * // 自定义输出目录和格式 * const result = await createWebFonts({ * input: './font.ttf', * outputDir: './dist/fonts', * text: '常用汉字', * formats: ['woff2', 'woff'] // 只生成 WOFF2 和 WOFF * }) * * @example * // 自定义文件名 * const result = await createWebFonts({ * input: './font.ttf', * text: 'ABC', * resolveFileName: ({ basename, ext }) => `${basename}.min.${ext}` * }) * // 输出: font.min.woff2, font.min.woff, font.min.ttf * * @example * // 检查生成结果 * const result = await createWebFonts({ input: 'font.ttf', text: 'Hello' }) * result.fonts.forEach(font => { * if (font.success) { * console.log(`✓ ${font.format}: ${font.path}`) * } else { * console.error(`✗ ${font.format} failed:`, font.error.message) * } * }) */ export async function createWebFonts({ input, outputDir, text, resolveFileName, formats = ['woff2', 'woff', 'ttf'], }) { // Input validation if (!input) { throw new Error('input parameter is required') } if (!text) { throw new Error('text parameter is required') } if (!Array.isArray(formats) || formats.length === 0) { throw new Error('formats must be a non-empty array') } const basename = path.basename(input, path.extname(input)) const targetDir = outputDir || path.resolve(path.dirname(input), './output') // Use Promise.allSettled for better error handling const results = await Promise.allSettled( formats.map(targetType => minifyFont({ input, output: path.resolve( targetDir, typeof resolveFileName === 'function' ? resolveFileName({ basename, ext: targetType }) : `${basename}.${targetType}` ), text, }) ) ) // Map results to detailed information const fonts = formats.map((format, index) => { const result = results[index] const filename = typeof resolveFileName === 'function' ? resolveFileName({ basename, ext: format }) : `${basename}.${format}` const fontPath = path.resolve(targetDir, filename) if (result.status === 'fulfilled') { return { format, path: fontPath, success: true, } } else { return { format, path: fontPath, success: false, error: result.reason, } } }) return { outputDir: targetDir, fonts, } }