oliverdavies.uk/source/_posts/using-pcss-extension-postcss-webpack-encore.md

4.4 KiB
Raw Permalink Blame History

title excerpt date tags
Using the pcss extension for PostCSS with Webpack Encore How to use the .pcss file extension for PostCSS files with Webpack Encore. 2020-04-01
encore
postcss
symfony
webpack

Ive been watching Christopher Pitt (assertchris)s streams on Twitch over the last few months, in one of which he was doing some work with Tailwind CSS and using a .pcss file extension for his PostCSS files.

I couldnt remember seeing this extension before, but this made a lot of sense to me compared to the standard .css extension - both to make it clear that its a PostCSS file and features like nesting can be used, and also for better integration and highlighting with IDEs and text editors such as PhpStorm.

Its also shorter that the .postcss extension, and has been suggested by @PostCSS on Twitter previously.

Some of my projects use Laravel Mix which support this extension by default, but some of them use Symfonys Webpack Encore which didnt seem to, so I decided to look into it. (Note that both are agnostic and not coupled to their respective frameworks, so can be used with other projects too including Drupal and Sculpin).

Updating Webpack Encores configuration

I was able to review the existing configuration and confirm this by using console.log() to output Encores generated webpack configuration - specifically the module rules.

console.log(Encore.getWebpackConfig().module.rules)

There I can see the the test for PostCSS supports the .css and .postcss file extensions, but not .pcss.

test: /\.(css|postcss)$/,

There is documentation on the Symfony website for adding custom webpack loaders and plugins but this wasnt quite what I needed, as I needed to edit the existing css loader rather than add a new one.

The page that I needed was Advanced Webpack Config - specifically the section on 'Having the full control on Loaders Rules'.

This suggests using .configureLoaderRule() and using that to override test directly.

It does though come with a warning:

This is a low-level method. All your modifications will be applied just before pushing the loaders rules to Webpack. It means that you can override the default configuration provided by Encore, which may break things. Be careful when using it.

My first pass was to add the full .pcss extension, but as this is a regular expression, I did a second pass that adds an second capturing group that would cover both PostCSS extensions.

// First pass
loaderRule.test = /\.(css|pcss|postcss)$/

// Second pass
loaderRule.test = /\.(css|p(ost)?css)$/

To see this running, go to https://opdavi.es/webpack-encore-pcss-regex.

The final configuration

This is my full webpack.config.js file for this site, including the .pcss extension support:

Encore
    .disableSingleRuntimeChunk()
    .cleanupOutputBeforeBuild()
    .setOutputPath('source/build/')
    .setPublicPath('/build')
    .addEntry('app', './assets/js/app.js')
    .enablePostCssLoader()
    .configureLoaderRule('css', loaderRule => {
        loaderRule.test = /\.(css|p(ost)?css)$/
    })
    .enableSourceMaps(!Encore.isProduction())

if (Encore.isProduction()) {
    Encore
        .enableVersioning()
        .addPlugin(new PurgecssPlugin(purgecssConfig))
} else {
    Encore.enableSourceMaps()
}

module.exports = Encore.getWebpackConfig()

Alternatively, you can view it in the codebase on GitHub.

Contributing back to Encore

Ive also submitted a pull request to Encore to add support for the .pcss extension by default: https://github.com/symfony/webpack-encore/pull/718. If accepted, then these changes in webpack.config.js would no longer be needed.