Bud 6.3.0 and SASS

I’ve got a bud.config.mjs set up for SASS variables per Roots/Sage 10 - how to import sass variables with new bud.config.js? - #3 by zzzap

That works up to Bud 6.2.0, but yarn dev fails as of 6.3.0 with:

[bud@6.3.0] [bud] › ✖  TypeError: Cannot read properties of undefined (reading 'setOptions')

I have console.log’ed in the tap function and compared 6.2.0 vs. 6.3.0 and noticed that app.build.items is in 6.3.0 otherwise identical but sass key is gone.

Then I compared the Bud releases in question and noticed that 6.3.0 no longer has bud/sources/@roots/bud-sass/src/env.ts, which had…:

interface Items {
resolveUrl: Build.Item
sass: Build.Item
}
…among some other definitions, which seem relevant.

The commit that removes the env.ts file is: 🧬 improve(patch): public path by kellymears · Pull Request #1549 · roots/bud · GitHub

I wonder if that’s causing the problem I’m having, and if so, how should I mitigate?

1 Like

Was too late last night, I’ve noticed now that the same commit moves the defs to bud/sources/@roots/bud-sass/src/index.ts.

However for some reason my project won’t work. Still looking…

The @roots/bud-sass loader registration now runs directly after the user config is processed.

You can use the same function as before, but just call it within a build.before callback:

  /**
   * Use the build.before action to
   * ensure that sass is available
   */
  app.hooks.action("build.before", async (app) => {
    /**
     * Override sass-loader options
     */
    app.build.items.sass.mergeOptions({
      additionalData: `@import "@styles/common/variables";`,
    });
  });

Sorry about that, I should have communicated this change in the release notes. This change makes it easier to use this extension in only one compiler, if you are running multiple compilers.

1 Like

That works, thanks for the update.

Related: #1580

I set up an integration test for additionalData so if the API were to shift again I’d be reminded to inform you.

I also added a simple interface for managing the sass loader options, so whenever we release the next patch you should be able to just do this:

bud.sass.setOption('additionalData', `@import "@styles/common/variables";`)
2 Likes

The above option will still work but I was thinking about it more and added a couple of additional functions.

Use bud.sass.importGlobal to globally import a stylesheet or array of stylesheets:

bud.sass.importGlobal('@src/styles/variables')
bud.sass.importGlobal([
  '@src/styles/variables',
  '@src/styles/mixins',
  '@src/styles/functions',
])

Use bud.sass.registerGlobal to globally define an arbitrary value or array of values:

bud.sass.registerGlobal('$foo: rgba(0, 0, 0, 1);')
bud.sass.registerGlobal([
  '$foo: rgba(0, 0, 0, 1);',
  '$bar: rgba(255, 255, 255, 1);',
])

These will be available in 6.3.3.

1 Like

Thanks! I was having a similar issue not being able to access bud.build.rules.sass after upgrading to 6.3.

Unfortunately doesn’t work for me. What did I wrong?

Error:

[bud@6.3.5] [bud] › ✖ TypeError: app.entry(...).purgecss(...).sass.importGlobal(...).assets is not a function at module.exports (/app/web/app/themes/pai/bud.config.js:29:6)

packajes.json

"devDependencies": {
    "@roots/bud": "6.3.5",
    "@roots/bud-entrypoints": "6.3.5",
    "@roots/bud-postcss": "6.3.5",
    "@roots/bud-purgecss": "6.3.5",
    "@roots/bud-sass": "6.3.5",
    "@roots/sage": "6.3.5",
    "purgecss-with-wordpress": "^4.1.0"
  },
  "dependencies": {
    "@barba/core": "^2.9.7",
    "@barba/prefetch": "^2.1.10",
    "normalize.css": "^8.0.1"
  }

bud.config.js

/**
 * @typedef {import('@roots/bud').Bud} bud
 *
 * @param {bud} app
 */
module.exports = async (app) => {
  app
    /**
     * Application entrypoints
     *
     * Paths are relative to your resources directory
     */
    .entry({
      app: ['@scripts/app', '@styles/app'],
      editor: ['@scripts/editor', '@styles/editor'],
    })

    .purgecss({
      content: [app.path('resources/views/**')],
      safelist: [...require('purgecss-with-wordpress').safelist],
    })

    .sass.importGlobal('@src/styles/core/variables')

    /**
     * These files should be processed as part of the build
     * even if they are not explicitly imported in application assets.
     */
    .assets('images')

    /**
     * These files will trigger a full page reload
     * when modified.
     */
    .watch('resources/views/**/*', 'app/**/*')

    /**
     * Target URL to be proxied by the dev server.
     *
     * This should be the URL you use to visit your local development server.
     */
    .proxy('http://pai-website.lndo.site')

    /**
     * Development URL to be used in the browser.
     */
    .serve('http://0.0.0.0:3000');
};

bud.sass.importGlobal does not return bud, it returns bud.sass.

Easiest way to handle is to start a new chain:

    // ...config
    .sass.importGlobal('@src/styles/core/variables'); // ends the first function chain

    app.assets('images') // <= start a new chain here

Or, you can use bud.tap

    // ...config
    .tap(app => app.sass.importGlobal('@src/styles/core/variables'))  // `bud.tap` always returns `bud`
    .assets('images')
1 Like

Thank you for your explanation! I apriciate it.

One more question:

I have the following Error:

SassError: This file is already being loaded.

I understand a reason, but I don’t know how to fix it.

Could you please help me with that and share a link to the docs? I can’t find that in the docs.

that’s more of a sass and/or sass-loader question, i think, and i’m not sure what the exact problem is.

i’m guessing you are already importing '@src/styles/core/variables' somewhere in one of your sass partials. You likely need to remove that import. Just a hunch, though, I don’t use this feature.

1 Like

Actually nope. I don’t have any other imports.

Interesting thing:

  1. If I import files via sass. I have errors like
SassError: Undefined variable.
  ╷
2 │   font-size: $fz-base;
  │              ^^^^^^^^

But the front works well. Styles compile right and work properly.

  1. if with app.sass.importGlobal('@src/styles/core/variables')) and keep app.scss empty or with styles which use variables I have error like and front works too
 ERROR  ./resources/styles/core/_variables.scss

FYI:
I have switched to PostCSS, and everything works right. I guess bud-sass @import doesn’t work right for files with mixins, vars etc.

No, it does.

Here is a codesandbox featuring global vars and mixins you can play around with:

Not to stop you from switching to postcss :stuck_out_tongue: