Bud.use doesn't work properly after at least bud v.6.6.10

I updated to the latest Bud version to get the advantage of using webp images in blade (with bud-imagemin), but it affected some other things.

I am using svg-spritemap-webpack-plugin with bud.use and it seems that something happend that doesn’t make it work.

It is like this in the bud.config.mjs file:

import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin'

export default async (app) => {
  app
// other things

    .use( // also tried with: await app.use
      new SVGSpritemapPlugin('resources/sprite/*.svg', {
        output: {
          filename: 'spritesheet.svg',
             chunk: { keep: true },
             svgo: false
        }
      })
    )

// other things

Normally this generates a spritesheet.svg file which has the svg that are included in the sprite folder. But after I upgrade to the latest version (also tried with v6.7.0) the file generated only has this
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

I looked at all the changelog from 6.6.10 upwards and didn’t find anything related to bud.use.

I think the plugin is unable to locate 'resources/sprite/*.svg', so you should probably wrap that string in an app.path function call. Your new config would look like this:

import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin'

export default async (app) => {
  app
// other things

    .use( // also tried with: await app.use
      new SVGSpritemapPlugin(app.path('resources/sprite/*.svg'), {
        output: {
          filename: 'spritesheet.svg',
             chunk: { keep: true },
             svgo: false
        }
      })
    )

// other things

Hey, thanks for the answer!

This doesn’t seem to make a difference, the same thing happens.

I’ve just tested this with 6.9.1 and the spritemap is still populated on my end. What does the rest of your bud.config look like? This is my working config (taken from bud.config.mjs):

// @ts-check
import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin';

/**
 * Build configuration
 *
 * @see {@link https://bud.js.org/guides/configure}
 * @param {import('@roots/bud').Bud} app
 */
export default async (app) => {
  app
    /**
     * Application entrypoints
     */
    .entry({
      app: ["@scripts/app", "@styles/app"],
      editor: ["@scripts/editor", "@styles/editor"],
    })

    /**
     * Directory contents to be included in the compilation
     */
    .assets(["images"])

    /**
     * Matched files trigger a page reload when modified
     */
    .watch(["resources/views/**/*", "app/**/*"])

    /**
     * Proxy origin (`WP_HOME`)
     */
    .proxy("http://mydomain.test")

    /**
     * Development origin
     */
    .serve("http://0.0.0.0:3000")

    /**
     * URI of the `public` directory
     */
    .setPublicPath(publicPath => {
      if (app.mode === 'production') {
        return `/wp-content/themes/theme-name/public/`
      } else {
        return `/app/themes/theme-name/public/`
      }
    })

    /**
     * Generate SVG sprite based on available icons
     */
    .use(
      new SVGSpritemapPlugin(app.path('resources/images/icons/*.svg'), {
        output: {
          filename: 'icons.svg',
          chunk: {keep: true},
          svgo: false,
        },
        sprite: {
          prefix: false,
        },
      }),
    )

    /**
     * Generate WordPress `theme.json`
     *
     * @note This overwrites `theme.json` on every build.
     */
    .wpjson
      .settings({
        color: {
          custom: false,
          customGradient: false,
          defaultPalette: false,
          defaultGradients: false,
        },
        custom: {
          spacing: {},
          typography: {
            'font-size': {},
            'line-height': {},
          },
        },
        spacing: {
          padding: true,
          units: ['px', '%', 'em', 'rem', 'vw', 'vh'],
        },
        typography: {
          customFontSize: false,
        },
      })
      .enable()
};

I am also testing it in an empty sage theme to be sure this problem isn’t only on my project.

This is the bud.condig.mjs:

import SVGSpritemapPlugin from 'svg-spritemap-webpack-plugin';

/**
 * Build configuration
 *
 * @see {@link https://roots.io/docs/sage/ sage documentation}
 * @see {@link https://bud.js.org/guides/configure/ bud.js configuration guide}
 *
 * @typedef {import('@roots/bud').Bud} Bud
 * @param {Bud} app
 */
export default async (app) => {
  /**
   * Application entrypoints
   * @see {@link https://bud.js.org/docs/bud.entry/}
   */
  app
    .entry({
      app: ['@scripts/app', '@styles/app'],
      editor: ['@scripts/editor', '@styles/editor'],
    })

    /**
     * Directory contents to be included in the compilation
     * @see {@link https://bud.js.org/docs/bud.assets/}
     */
    .assets(['images'])

    /**
     * Matched files trigger a page reload when modified
     * @see {@link https://bud.js.org/docs/bud.watch/}
     */
    .watch(['resources/views', 'app'])

    /**
     * Proxy origin (`WP_HOME`)
     * @see {@link https://bud.js.org/docs/bud.proxy/}
     */
    .proxy('http://bedrock.test')

    /**
     * Development origin
     * @see {@link https://bud.js.org/docs/bud.serve/}
     */
    .serve('http://bedrock.test:3000')

    /**
     * URI of the `public` directory
     * @see {@link https://bud.js.org/docs/bud.setPublicPath/}
     */
    .setPublicPath('/app/themes/sage/public/')

    .use(
      new SVGSpritemapPlugin(app.path('resources/sprite/*.svg'), {
        output: {
          filename: 'spritesheet.svg',
          chunk: { keep: true },
          svgo: false,
        },
      })
    )

    /**
     * Generate WordPress `theme.json`
     *
     * @note This overwrites `theme.json` on every build.
     *
     * @see {@link https://bud.js.org/extensions/sage/theme.json/}
     * @see {@link https://developer.wordpress.org/block-editor/how-to-guides/themes/theme-json/}
     */
    .wpjson.settings({
      color: {
        custom: false,
        customDuotone: false,
        customGradient: false,
        defaultDuotone: false,
        defaultGradients: false,
        defaultPalette: false,
        duotone: [],
      },
      custom: {
        spacing: {},
        typography: {
          'font-size': {},
          'line-height': {},
        },
      },
      spacing: {
        padding: true,
        units: ['px', '%', 'em', 'rem', 'vw', 'vh'],
      },
      typography: {
        customFontSize: false,
      },
    })
    .useTailwindColors()
    .useTailwindFontFamily()
    .useTailwindFontSize()
    .enable();
};

Now the thing is that on yarn dev the spritesheet.svg gets generated as it should, but on yarn build it doesn’t.

Does the same thing happen to you?

Just did a clean install as well, copied your config above and added a directory called sprite in resources containing a single svg. After running yarn build a spritesheet.svg is created in public with the referenced svg included.

I’m not sure what else could be at fault here. SVGSpritemapPlugin complains quite loudly if the directory isn’t present or empty and it also returns parser errors when any of the SVGs is malformed. I reckon there’s no error output on the terminal when running yarn build?

Have you tried running the command using other SVGs, coming from FontAwesome or another verified source? As yarn dev generates a populated sprite for you, but build doesn’t, it could be related to the clean-up and minify routines that run on the latter command, maybe it’s too eager on those individual SVGs?

There are a couple of issues on Github (here and here) regarding empty sprites, but no clear solution.

1 Like

Just to confirm, nothing changed with bud extensions API.

Here’s a sandbox with the plugin working with the code as provided (you can run build or dev; both seem to be working):

Depending on how that plugin is coded (I’m not familiar with it outside of a bud support context) it might have a funky cache. The webpack caching APIs are… interesting.

yarn bud build --force will force recompiling all modules regardless of their cache status. This would track with the dev/build discrepancy – when bud calculates a cache identifier for the command being run it includes the args/flags passed via cli. In other words, yarn bud build and yarn bud dev have separate caches.