UNPKG

vite-plugin-font

Version:

An automatic Web Font optimization plugin that supports many platforms such as Vite, Next, Nuxt, and more.

116 lines (111 loc) 3.56 kB
'use strict'; Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const index = require('./index.js'); const glob = require('glob'); const fs = require('fs-extra'); const crypto = require('node:crypto'); const path = require('path'); const minimatch = require('minimatch'); class SubsetUtils { static isSubsetLink(p) { const [idString, params] = p.split("?"); const searchParams = new URLSearchParams(params); const isSubset = searchParams.has("subsets"); return { idString, isSubset, searchParams }; } static emptyCacheDir(config) { if (!config.cacheDir) throw new Error("vite-plugin-font | cacheDir missed"); const dir = path.resolve(config.cacheDir, ".subsets"); return fs.emptyDir(dir); } } class SubsetBundlePlugin extends index.BundlePlugin { constructor(config, key) { super(config, key); this.usedSubsets = /* @__PURE__ */ new Set(); this.isSubsetLink = SubsetUtils.isSubsetLink; this.subsetConfig = config; this.subsetCacheDir = config.cacheDir; } getCachedPath(p) { const { isSubset, idString } = this.isSubsetLink(p); return path.resolve( isSubset ? this.subsetCacheDir : this.config.cacheDir, index.getFileName(idString) ); } async createSubsetsHash() { if (!this.subsetConfig.scanFiles) return; this.getWhiteListSubsets(); await this.updateScanFiles(); const subsetsArr = [...this.usedSubsets].sort((a, b) => a - b); this.subsets = [subsetsArr]; const hash = crypto.createHash("md5").update(String.fromCodePoint(...subsetsArr)).digest("hex"); this.subsetCacheDir = path.resolve( this.config.cacheDir, ".subsets", hash ); return hash; } /** 匹配绝对路径是否被获取到 */ isMatchScanArea(p) { const globStr = this.getGlobArea(); if (!globStr) return false; const resolvePath = (p2) => path.resolve(process.cwd(), p2); if (globStr instanceof Array) { return globStr.some((i) => minimatch.minimatch(p, resolvePath(i))); } return minimatch.minimatch(p, resolvePath(globStr)); } /** 获取配置中的 scanFiles 字段 */ getGlobArea() { if (typeof this.subsetConfig.scanFiles === "object" && !(this.subsetConfig.scanFiles instanceof Array)) { return this.subsetConfig.scanFiles[this.key]; } else { return this.subsetConfig.scanFiles; } } async updateScanFiles() { const globStr = this.getGlobArea(); if (!globStr) return; const files = await glob.glob(globStr, { absolute: true, nodir: true, ignore: this.subsetConfig.ignore ?? ["node_modules/**"] }); return Promise.all( files.map((i) => { return new Promise((res, rej) => { const stream = fs.createReadStream(i, { encoding: "utf8" }); stream.on("data", (i2) => { [...i2].forEach( (char) => this.usedSubsets.add(char.codePointAt(0)) ); }); stream.on("end", () => { res(null); }); stream.on("error", (err) => { rej(err); }); }); }) ); } getWhiteListSubsets() { let whiteList = this.subsetConfig.whiteList ?? []; if (!(whiteList instanceof Array)) { whiteList = [whiteList]; } const set = this.usedSubsets; whiteList.forEach( (str) => [...str].forEach((char) => set.add(char.codePointAt(0))) ); } } exports.SubsetBundlePlugin = SubsetBundlePlugin; exports.SubsetUtils = SubsetUtils;