@subframe7536/fonttools
Version:
[ESM only] fonttools for nodejs or web with vite plugin, powered by pyodide
149 lines (146 loc) • 5.3 kB
JavaScript
import fs from 'node:fs';
import { createRequire } from 'node:module';
import path from 'node:path';
import { createLogger } from 'vite';
// <define:__ASSETS__>
var define_ASSETS_default = ["brotli-1.1.0-cp312-cp312-pyodide_2024_0_wasm32.whl", "fonttools-4.51.0-py3-none-any.whl", "pyodide.asm.wasm", "python_stdlib.zip", "pyodide-lock.json", "pyodide.web.asm.js"];
var assetsKey = {
brotli: "$brotli",
fonttools: "$fonttools",
wasm: "$wasm",
asmjs: "$asmjs",
zip: "$zip",
lock: "$lock"
};
var logger = createLogger("info", { prefix: "[fonttools]" });
function fonttools(options = {}) {
const {
customURL = (key, _, finalMap) => path.basename(finalMap.get(key)[0]),
transformAsmJs
} = options;
const fonttoolsDistRoot = path.dirname(createRequire(import.meta.url).resolve("@subframe7536/fonttools"));
const assetsNameMap = /* @__PURE__ */ new Map();
const finalAssetsPathMap = /* @__PURE__ */ new Map();
const importers = [];
let outputDir = "dist";
return [
{
name: "vite-plugin-fonttools-exclude",
enforce: "pre",
config(config) {
config.optimizeDeps?.exclude?.push("@subframe7536/fonttools");
}
},
{
name: "vite-plugin-fonttools",
apply: "build",
enforce: "post",
buildStart() {
for (const fileName of define_ASSETS_default) {
let key;
switch (true) {
case fileName.startsWith("brotli"):
key = assetsKey.brotli;
break;
case fileName.startsWith("fonttools"):
key = assetsKey.fonttools;
break;
case fileName.includes("web.asm"):
key = assetsKey.asmjs;
break;
case fileName.includes("wasm"):
key = assetsKey.wasm;
break;
case fileName.includes("zip"):
key = assetsKey.zip;
break;
case fileName.includes("lock"):
key = assetsKey.lock;
break;
default:
logger.warn(`Unknown assets: ${fileName}`, { timestamp: true });
}
if (key) {
assetsNameMap.set(key, fileName);
}
this.emitFile({
type: "asset",
name: fileName,
originalFileName: key,
source: fs.readFileSync(
path.join(fonttoolsDistRoot, fileName),
fileName.endsWith(".js") ? "utf-8" : void 0
)
});
}
},
writeBundle(options2, bundle) {
if (options2.dir) {
outputDir = options2.dir;
}
for (const [filePath, info] of Object.entries(bundle)) {
if (info.type === "chunk") {
if (info.code.includes("pyodide.web.asm.js")) {
importers.push([path.join(outputDir, filePath), info.code]);
}
} else {
const key = info.originalFileNames[0];
if (assetsNameMap.has(key)) {
finalAssetsPathMap.set(key, [filePath, info.source]);
}
}
}
},
closeBundle() {
if (importers.length < 1) {
logger.warn(`No importer found, skip`, { timestamp: true });
return;
}
for (const importer of importers) {
const [importerPath, importerCode] = importer;
const [lockFilePath, lockFileSource] = finalAssetsPathMap.get(assetsKey.lock);
const json = JSON.parse(lockFileSource);
json.packages.brotli.file_name = customURL(
assetsKey.brotli,
assetsNameMap,
finalAssetsPathMap,
importer
);
json.packages.fonttools.file_name = customURL(
assetsKey.fonttools,
assetsNameMap,
finalAssetsPathMap,
importer
);
const lockFileFinalPath = path.join(outputDir, lockFilePath);
fs.writeFileSync(lockFileFinalPath, JSON.stringify(json));
logger.info(`Update lock file: ${lockFileFinalPath}`, { timestamp: true });
const updatedImporterCode = importerCode.replace(
assetsNameMap.get(assetsKey.asmjs),
customURL(assetsKey.asmjs, assetsNameMap, finalAssetsPathMap, importer)
).replace(
assetsNameMap.get(assetsKey.wasm),
customURL(assetsKey.wasm, assetsNameMap, finalAssetsPathMap, importer)
).replace(
assetsNameMap.get(assetsKey.zip),
customURL(assetsKey.zip, assetsNameMap, finalAssetsPathMap, importer)
).replace(
assetsNameMap.get(assetsKey.lock),
customURL(assetsKey.lock, assetsNameMap, finalAssetsPathMap, importer)
);
fs.writeFileSync(importerPath, updatedImporterCode);
logger.info(`Update importer: ${importerPath}`, { timestamp: true });
}
const asmJsPath = finalAssetsPathMap.get(assetsKey.asmjs)[0];
if (typeof transformAsmJs === "function") {
const code = fs.readFileSync(asmJsPath, "utf-8");
const updatedCode = transformAsmJs(code);
if (updatedCode) {
fs.writeFileSync(asmJsPath, updatedCode, "utf-8");
}
}
}
}
];
}
export { assetsKey, fonttools };