UNPKG

@subframe7536/fonttools

Version:

[ESM only] fonttools for nodejs or web with vite plugin, powered by pyodide

149 lines (146 loc) 5.3 kB
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 };