vite-plugin-font
Version:
An automatic Web Font optimization plugin that supports many platforms such as Vite, Next, Nuxt, and more.
108 lines (105 loc) • 3.4 kB
JavaScript
import { createUnplugin } from 'unplugin';
import { SubsetUtils, SubsetBundlePlugin } from './subset/SubsetBundlePlugin.mjs';
import { normalizePath } from './utils/normalizePath.mjs';
class UnionFontPlugin {
constructor() {
this.config = {};
this.pluginStore = /* @__PURE__ */ new Map();
}
async start() {
if (this.prepared) return this.prepared;
if (!this.config.cacheDir)
this.config.cacheDir = "node_modules/.cache/.font";
let resolve;
this.prepared = new Promise((res) => {
resolve = res;
});
if (this.config.emptyCacheDir === true) {
await SubsetUtils.emptyCacheDir(this.config);
console.log(
"vite-plugin-font | empty cache dir | " + this.config.cacheDir,
"\nemptyCacheDir: false to cancel this behavior."
);
await this.getUsingPlugin("default");
console.log(
"vite-plugin-font | cache dir | " + this.config.cacheDir
);
}
resolve(null);
}
createConfig(config) {
const scanFiles = typeof config.scanFiles === "object" && !(config.scanFiles instanceof Array) ? config.scanFiles : {
default: config.scanFiles
};
this.config = { ...config, scanFiles };
}
getCacheDir() {
return this.config.cacheDir ?? "node_modules/.cache/.font";
}
setCacheDir(cacheDir) {
this.config.cacheDir = cacheDir;
}
async getUsingPlugin(key) {
let usingPlugin = this.pluginStore.get(key);
if (!usingPlugin) {
usingPlugin = new SubsetBundlePlugin(this.config);
usingPlugin.key = key;
this.pluginStore.set(key, usingPlugin);
}
await usingPlugin.createSubsetsHash();
return usingPlugin;
}
/** 通过改动文件的 path 获取需要变更的 plugin */
getWatchingPlugin(path) {
let matchedPlugins = [];
this.pluginStore.forEach((plugin, key) => {
if (plugin.isMatchScanArea(path)) {
matchedPlugins.push(plugin);
}
});
return matchedPlugins;
}
}
const unpluginFactory = (config = {}) => {
const include = config.include ?? [/\.otf/, /\.ttf/];
const exclude = config.exclude ?? [/\/node_modules\//];
const plugin = new UnionFontPlugin();
plugin.createConfig(config);
return {
name: "vite-plugin-font",
loadInclude(id) {
id = normalizePath(id);
if (exclude.some((i) => i.test(id))) return false;
return include.some((i) => i.test(id));
},
enforce: "pre",
vite: {
async configResolved(c) {
plugin.setCacheDir(c.cacheDir);
await plugin.start();
},
/** 先对 vite 进行热更新支持 */
handleHotUpdate(ctx) {
const plugins = plugin.getWatchingPlugin(ctx.file);
return ctx.modules.concat(
plugins.map((i) => {
return ctx.server.moduleGraph.getModuleById(
i.buildId
);
})
);
}
},
async load(id) {
await plugin.start();
const { isSubset, searchParams } = SubsetUtils.isSubsetLink(id);
const key = searchParams.get("key") ?? "default";
const usingPlugin = await plugin.getUsingPlugin(key);
await usingPlugin.prebuild(id, isSubset ? "subsets" : "full");
usingPlugin.buildId = id;
return usingPlugin.createSourceCode(id);
}
};
};
const fontPlugin = /* @__PURE__ */ createUnplugin(unpluginFactory);
export { fontPlugin as default, fontPlugin, unpluginFactory };