1
0
Fork 0
tsgames/build/fontPlugin.ts

76 lines
2.7 KiB
TypeScript

import { plugin, type BunPlugin } from "bun";
import path from 'path';
const fontPlugin: BunPlugin = {
name: "Font loader",
async setup(build) {
build.onResolve({ filter: /^__style_helper__$/ }, (args) => {
return {
path: args.path,
namespace: 'style-helper',
}
});
build.onLoad({ filter: /.*/, namespace: 'style-helper' }, async () => {
return {
contents: `
export default function injectStyle(text) {
if (typeof document !== 'undefined') {
let styleTag = document.querySelector('style')
if (!styleTag) {
styleTag = document.createElement('style')
document.head.appendChild(styleTag)
}
styleTag.appendChild(document.createTextNode(text))
}
}
`,
loader: 'js',
}
})
build.onLoad({ filter: /\.font\.css$/ }, async (args) => {
let css = await Bun.file(args.path).text();
const regex = /url\(['"]?(?!data:)([^'")]*)['"]?\)/;
let match: RegExpExecArray | null = null;
while ((match = regex.exec(css)) != null) {
if (match?.[1]) {
let buffer: Buffer | null = null;
const fontName = match[1];
if (fontName.startsWith('http')) {
const response = await fetch(fontName);
if (response.ok) {
buffer = Buffer.from(await response.arrayBuffer());
}
} else {
const fontPath = path.resolve(path.dirname(args.path), fontName);
const fontFile = Bun.file(fontPath);
if (await fontFile.exists()) {
buffer = Buffer.from(await fontFile.arrayBuffer());
}
}
if (buffer) {
const url = `data:;base64,${buffer.toString('base64')}`;
css = css.replace(fontName, url);
}
}
}
const updatedCSS = css
.replace(/(\n\s*)*/g, '')
.replace(/;\s*\}/g, '}')
.replace(/\s*([{:])\s*/g, '$1');
return {
contents: `import i from '__style_helper__';i(${JSON.stringify(updatedCSS)})`,
loader: 'js',
};
});
}
};
plugin(fontPlugin);
export default fontPlugin;