Skip to content

Migrate My Blog to Astro

Changes made to original theme.

1 min read

Dynamic Class Extraction from data.json#

By default, the original author uses safelist to ensure Unocss generates the required classes for the project icons. And this is only handled once at the build time. When dynamically change the content of data.json, the icons are missing.

Solution: use a custom extractor to extract icon classes from the file.

unocss.config.ts
...
transformerDirectives,
transformerVariantGroup,
extractorSplit,
} from 'unocss'
import type { ProjectSchema } from '~/content/schema'
const projectIcons = projecstData.map((item) => item.icon)
// const projectIcons = projecstData.map((item) => item.icon)
...
export default defineConfig({
// Astro 5 no longer pipes `src/content/**/*.{md,mdx}` through Vite
content: {
filesystem: ['./src/{content,pages}/**/*.{md,mdx}'],
// dev HMR
pipeline: {
include: [
// the default
/\.(vue|svelte|[jt]sx|vine.ts|mdx?|astro|elm|php|phtml|html)($|\?)/,
'./src/content/projects/data.json',
],
// exclude files
// exclude: []
},
// build phase
filesystem: [
'./src/content/projects/data.json',
'./src/{content,pages}/**/*.{mdx,md}',
],
},
extractors: [
{
name: "antfustyle-astro-theme/data-extractor",
extract(ctx) {
if (!ctx.id)
return undefined
if (ctx.id?.endsWith("projects/data.json")) {
try {
return (JSON.parse(ctx.code) as ProjectSchema[]).map((v) => v.icon)
}
// eslint-disable-next-line no-empty
catch { }
}
},
},
extractorSplit,
],
...
// work around the limitation of dynamically constructed utilities
// https://unocss.dev/guide/extracting#limitations
safelist: [
...navIcons,
...socialIcons,
...projectIcons,
// ...projectIcons,
NOTE

TODO: unfinished