Using the `postcss.plugins` Bud hook to reorder PostCSS plugins

Hi!

I’m trying to use the postcss.plugins hook to reorder my plugins as described the @roots/bud-postcss documentation. I’m trying to use the postcss-import-ext-glob plugin, which must be placed before postcss-import. I can get the glob plugin to import, but I’m not able to get it to run before postcss-import and my builds are failing.

My project is a fresh install of Sage 10.6.0. I’m using Node v18.16.0 with Yarn 1.22.10. I’ve added the postcss-import-ext-glob plugin using yarn add -D postcss-import-ext-glob. I’ve modified my Bud config, main app css, and created a CSS file to import via glob. Here is the contents of those files, relative to the Sage root:

bud.config.js:

/**
 * Compiler configuration
 *
 * @see {@link https://roots.io/docs/sage sage documentation}
 * @see {@link https://bud.js.org/guides/configure bud.js configuration guide}
 *
 * @param {import('@roots/bud').Bud} app
 */
export default async (app) => {

  /**
   * Application assets & entrypoints
   *
   * @see {@link https://bud.js.org/docs/bud.entry}
   * @see {@link https://bud.js.org/docs/bud.assets}
   */
  app
    .entry('app', ['@scripts/app', '@styles/app'])
    .entry('editor', ['@scripts/editor', '@styles/editor'])
    .assets(['images']);

  /**
   * Set public path
   *
   * @see {@link https://bud.js.org/docs/bud.setPublicPath}
   */
  app.setPublicPath('/app/themes/sage/public/');

  /**
   * Development server settings
   *
   * @see {@link https://bud.js.org/docs/bud.setUrl}
   * @see {@link https://bud.js.org/docs/bud.setProxyUrl}
   * @see {@link https://bud.js.org/docs/bud.watch}
   */
  app
    .setUrl('http://localhost:3000')
    .setProxyUrl('http://example.test')
    .watch(['resources/views', 'app']);


  /**
   * PostCSS plugin settings
   */
  app
    .postcss.setPlugin('postcss-import-ext-glob');


  app.hooks.on('postcss.plugins', () => {
    return [
      app.postcss.get('postcss-import-ext-glob'),
      app.postcss.get('import'),
      app.postcss.get('nesting'),
      app.postcss.get('tailwindcss'),
      app.postcss.get('env'),
    ]
  });

  /**
   * 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}
   */
  app.wpjson
    .set('settings.color.custom', false)
    .set('settings.color.customDuotone', false)
    .set('settings.color.customGradient', false)
    .set('settings.color.defaultDuotone', false)
    .set('settings.color.defaultGradients', false)
    .set('settings.color.defaultPalette', false)
    .set('settings.color.duotone', [])
    .set('settings.custom.spacing', {})
    .set('settings.custom.typography.font-size', {})
    .set('settings.custom.typography.line-height', {})
    .set('settings.spacing.padding', true)
    .set('settings.spacing.units', ['px', '%', 'em', 'rem', 'vw', 'vh'])
    .set('settings.typography.customFontSize', false)
    .useTailwindColors()
    .useTailwindFontFamily()
    .useTailwindFontSize()
    .enable();
};

resources/styles/app.css:

@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
@import-glob 'base/**/*.css';

resources/styles/base/elements.css (new file):

@layer base {
  body {
    @apply text-green-950;
  }
}

The error I get on yarn build is the error output I expect from a Tailwind + PostCSS setup using the postcss-import-ext-glob plugin when postcss-import-ext-glob is not run before postcss-import. (I tested this on a Mix project using these plugins by swapping those two plugins’ order; when postcss-import was first I received similar errors). Results of yarn build:

yarn run v1.22.10
$ bud build

╭─ ✘ sage ./public [827b91f50582c0a030c1]
│
├─ ✘  error
│
│
│
│ (1:1) ./resources/styles/base/elements.css `@layer base` is used but no matching `@tailwind base` directive is present.
│
│ > 1 | @layer base {
│     | ^
│   2 |   body {
│   3 |     @apply text-green-950;
│
│
├─ entrypoints
│  ├─ app
│  │  ├─ js/runtime.00900e.js     1.22 kB
│  │  ├─ js/259.6cf96b.js       291 bytes
│  │  └─ js/app.6b14e3.js        20.39 kB
│  └─ editor
│     ├─ js/runtime.00900e.js     1.22 kB
│     ├─ js/515.f9de99.js       940 bytes
│     ├─ css/editor.31d6cf.css    0 bytes
│     └─ js/editor.3d4e12.js       1.2 kB
│
╰─ compiled 27 modules (25 cached) in 402ms

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

And the results of yarn build --verbose: yarn run v1.22.10$ bud build --verbose[env] › ▶ sourcing .env values Initia - Pastebin.com (sorry to post it externally but the verbose log exceeds the Discourse character limit)

I’m not sure the postcss.plugins hook is ever fired. I’ve tried adding a debug message into it with console.log() and running yarn build --verbose and the debug message is never printed (it was when I tried with the build.externals hook). And returning an empty array in the postcss.plugins hook doesn’t appear to affect the build either.

1 Like

@thunderdw, sorry for the belated reply, thank you for your descriptive issue.

I kind of dropped the ball on this.

Looking at the code (and docs) I realized they both could be improved in many ways. Again, my apologies for this being in a poor state and for any frustration it caused.

I have implemented those improvements and they are currently released on nightly. I will ideally be pulling together a 6.13.0 release in the coming days that feature these changes.

The existing API doesn’t really change but there is the addition of a new function (bud.postcss.use) to make it easier to order plugins.

Sandbox running 2023.5.23

I went with a very different postcss config for this:

export default async (bud) =>
  bud.postcss
    .setPlugin(`postcss-import`)
    .setPlugin(`postcss-simple-vars`)
    .setPlugin(`postcss-nested`)
    .setPlugin(`postcss-mixins`)
    .setPlugin(`postcss-preset-env`)
    .use([
      `postcss-import`,
      `postcss-simple-vars`,
      `postcss-nested`,
      `postcss-mixins`,
      `postcss-preset-env`,
    ])

Updated documentation

https://github.com/roots/bud/blob/9c6704fc94c3dc90842e944c7dfad7e5776499f2/sources/%40repo/docs/content/extensions/bud-postcss.mdx

Thoughts?

If you wanted to try it out before the proper release you could install 2023.5.23. I’m hopeful you find the changes to be satisfactory; let me know if there is anything else I can/should address with regards to the problems you encountered :pray:t3:.

3 Likes

No worries at all and thank you for working on this!

I played around with the 2023.5.23 version of things and everything is working perfectly and the docs are great.

Thanks again!

1 Like