Skip to main content

@roots/bud-postcss

PostCSS can be added by installing the @roots/bud-postcss extension.

Installation​

yarn add @roots/bud-postcss --dev

Usage​

By default, @roots/bud-postcss includes the following plugins, registered with postcss in this order:

OrderKeyPlugin
1.'import'postcss-import
2.'nesting'postcss-nested
3.'env'postcss-preset-env

If this works for you, great! No need to keep reading. But, should you need something more specialized, you can configure it in your bud config file or a postcss.config.js file in your project's root directory.

Any additional plugins you may want to add will be added between nesting and env. This is, generally, what you want, but there instructions included below for overriding this behavior.

Add a plugin​

You can add a plugin with bud.postcss.setPlugin. This function takes up to two parameters.

The first parameter is required. It is the name for the plugin. If it is the only parameter being passed, it should be the module signifier.

bud.config.js
bud.postcss.setPlugin('example-postcss-plugin')

The second parameter is optional and multivariate.

Use a string to specify the plugin's resolvable path:

bud.config.js
bud.postcss.setPlugin(
'example-postcss-plugin',
bud.path('./directory/example.js'),
)

Use an array to set any associated options alongside the resolvable path.

bud.config.js
bud.postcss.setPlugin('example-postcss-plugin', [
bud.path('./directory/example.js'),
{stage: 1},
])

Override plugin options​

You can modify options for a plugin using bud.postcss.setPluginOptions.

The first parameter is the plugin key and the second is the options object.

bud.config.js
bud.postcss.setPluginOptions('example-postcss-plugin', {optimize: false})

Override plugin resolution​

You can modify the path for a postcss plugin using bud.postcss.setPluginPath.

The first parameter is the plugin key and the second is the new path to assign.

bud.config.js
bud.postcss.setPluginPath(
'example-postcss-plugin',
bud.path('./lib/my-plugin.js'),
)

Add multiple plugins​

You can add multiple postcss plugins using bud.postcss.setPlugins.

Using an object​

bud.config.js
bud.postcss.setPlugins({
['tailwindcss']: await bud.module.resolve('tailwindcss'),
['nesting']: await bud.module.resolve('tailwindcss/nesting/index.js'),
})

Using a Map​

bud.config.js
bud.postcss.setPlugins(
new Map([])
.set('tailwindcss', await bud.module.resolve('tailwindcss'))
.set('nesting', [
await bud.module.resolve('tailwindcss/nesting/index.js'),
]),
)

Using an array​

bud.config.js
bud.postcss.setPlugins([
['tailwindcss', await bud.module.resolve('tailwindcss')],
['nesting', await bud.module.resolve('tailwindcss/nesting/index.js')],
])

Remove a plugin​

You may remove a plugin with bud.postcss.unsetPlugin.

bud.config.js
bud.postcss.unsetPlugin('import')

Plugin ordering​

@roots/bud-postcss loosely attempts to enforce a particular plugin load order.

It will always attempt to load plugins in this order:

OrderDescriptionDefault
1import implementationpostcss-import
2nesting implementationpostcss-nested
...3all other plugins as registerednone
4env implementationpostcss-preset-env

The reason bud.js gets so hands-on here is to provide a reasonable default which people can build on without needing to splice in their own plugins manually. If this is a problem for your project, the most direct way to override this is to hook a function to postcss.plugins which returns an array of plugin values:

bud.config.js
bud.hooks.on('postcss.plugins', () => {
return [
bud.postcss.get('import'),
// ... plugins, in the order you wish to load them
]
})

Working with the plugin registry directly​

@roots/bud-postcss stores PostCSS plugins as a Map. You can work with this Map directly using bud.postcss.plugins.

bud.config.js
export default async bud => {
bud.postcss.plugins.set('import', [
await module.resolve('postcss-import'),
{...options},
])

bud.postcss.plugins.get('import')

bud.postcss.plugins.delete('import')

bud.postcss.plugins.clear()
}

When you get something, you can hopefully rely on it being a tuple with the plugin in the first position and the options in the second. The plugin might be a string (resolveable path) or a module.