76 lines
2.7 KiB
TypeScript
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; |