Resolve asset to public path in `bud.config.js`/JavaScript

Thanks @strarsis for your insights. I tried to make this config more dynamic and ended now with:

export default async (app) => {

  /* ... */

  .useTailwindColors(true)
  // We don't want to use fonts configured in tailwind.config.js., so we disable
  // .useTailwindFontFamily()
  .useTailwindFontSize();

  /**
   * Set up fonts
   */
  app.setPath('@fonts', '@src/fonts');

  // Define font families
  const fontFamilies = {
    'barlow-condensed': {
      fontFamily: 'Barlow Condensed, sans-serif',
      slug: 'sans',
      name: 'Barlow Condensed',
      fontFace: [
        {
          fontFamily: 'Barlow Condensed',
          fontStyle: 'normal',
          fontWeight: 500,
          fontDisplay: 'swap',
          src: [
            '@fonts/barlow-condensed/files/barlow-condensed-latin-ext-500-normal.woff2',
            '@fonts/barlow-condensed/files/barlow-condensed-latin-500-normal.woff2'
          ],
        },
        {
          fontFamily: 'Barlow Condensed',
          fontStyle: 'italic',
          fontWeight: 500,
          fontDisplay: 'swap',
          src: [
            '@fonts/barlow-condensed/files/barlow-condensed-latin-ext-500-italic.woff2',
            '@fonts/barlow-condensed/files/barlow-condensed-latin-500-italic.woff2'
          ],
        },
      ]
    },
    'abril-fatface': {
      fontFamily: 'Abril Fatface, serif',
      slug: 'serif',
      name: 'Abril Fatface',
      fontFace: [
        {
          fontFamily: 'Abril Fatface',
          fontWeight: 400,
          fontDisplay: 'swap',
          src: [
            '@fonts/abril-fatface/files/abril-fatface-latin-ext-400-normal.woff2',
            '@fonts/abril-fatface/files/abril-fatface-latin-400-normal.woff2'
          ],
        }
      ],
    },
  };

  // Set font families in theme.json
  app.wpjson.settings(theme => theme.set('typography.fontFamilies', Object.values(fontFamilies)));

  // Copy all font files from @fontsource to @fonts
  for (const [id, font] of Object.entries(fontFamilies)) {
    await app.fs.copy(
      app.path(`@modules/@fontsource/${id}`),
      app.path(`@fonts/${id}`),
      {
        overwrite: true,
      }
    );
  }

  // Copy all font files to public directory
  app.assets(
    Object.values(fontFamilies)
      .flatMap(({ fontFace }) => fontFace)
      .flatMap(({ src }) => src)
      .map(src => app.path(src))
  );

  // Update theme.json with public paths
  app
    .after(async () => {
      const manifest = await app.fs.read(`public/manifest.json`);
      const data = app.container(await app.fs.read(`theme.json`));
      const fonts = data.get(`settings.typography.fontFamilies`);

      fonts.forEach((font, fontIndex) => {
        font.fontFace.forEach((face, faceIndex) => {
          data.set(
            `settings.typography.fontFamilies.[${fontIndex}].fontFace.[${faceIndex}].src`,
            face.src.map((src) => `file:./public/${manifest[src.split('/').pop()]}`)
          );
        });
      });

      await app.fs.write(`theme.json`, data.all());
    });
};

Maybe this could be simplified by a custom bud.js extensions for font handling, where we just config the fontFamilies object.

1 Like