Search code examples
webpackpostcssnuxt.js

Use sugarss with nuxt 2


I'm trying to use the postcss sugarss syntax in my nuxt project.

I've tried a variety of things:

Pushing a special sss rule to config.module.rules (this is what I'd prefer).

Here's basically what I've been trying in nuxt.config.ts and build.extend:

// earlier on at the top level I have this
css: [ '@/assets/css/main.sss' ],

extend(config) {
    config.module = config.module || { rules: [] }
    config.module.rules.push({
        test: /\.sss$/,
        use: [
            // 'vue-loader',
            // 'style-loader',
            // { loader: 'css-loader', options: { importLoaders: 1 } },
            'postcss-loader?parser=sugarss',
        ]
    })
}

This example (with only the postcss-loader actually engaged) doesn't successfully add styles to the rendered page. So for example with these files:

/* tailwind.css */
@tailwind base;

@tailwind components;

@tailwind utilities;
// main.sss
@import './tailwind.css'

a
    color: green

the links aren't green and none of the tailwind utilities work.

I know nuxt is processing those files, because if I make syntax errors in them the build fails.

Uncommenting any of those other loaders also doesn't help in any combination I've tried, but I'll admit I'm just shooting in the dark.

I'm fairly confident that the problem with this approach is that I'm not properly hooking into the nuxt webpack style loader chain, but I'm not sure how to do that. I looked at this boilerplate example from JGJP, but he's using a version of nuxt 1.0, and the 'nuxt/lib/builder/webpack/style-loader.js' file he's importing no longer exists. Nuxt has some similar concepts in packages/webpack/src/utils/style-loader.js, but I couldn't import those, and besides I'm not even sure that would help.

I also can't find any examples of people adding non-standard stylesheet syntaxes to nuxt.

Setting my build.postcss.parser to sugarss, which causes all the normal css in places like the .nuxt directory to break.

ERROR  in ./.nuxt/components/nuxt-loading.vue?vue&type=style&index=0&lang=css&

Syntax Error: SyntaxError
(157:16) Unnecessary curly bracket

  155 | 
  156 | 
> 157 | .nuxt-progress {
      |                ^
  158 |   position: fixed;
  159 |   top: 0px;

Adding a special postcss.config.js file to my src directory with the parser set to sugarss, so that only my css files would be parsed that way. But that doesn't work, I still get the .nuxt errors described above, as well as these warnings:

WARN  Please use build.postcss in your nuxt.config.js instead of an external config file. Support for such files will be removed in Nuxt 3 as they remove all defaults set by Nuxt and can cause severe problems with features like alias resolving inside your CSS.

WARN  You did not set any plugins, parser, or stringifier. Right now, PostCSS does nothing. Pick plugins for your case on https://www.postcss.parts/ and use them in postcss.config.js. 

The second warning doesn't make a ton of sense, since neither the nuxt.build.postcss config nor the special directory config were empty.

Thanks in advance!


Solution

  • I was able to figure it out by console.loging the existing config.module.rules passed in to extend(config), and shamelessly copying it. Here's the solution I ended up with.

    const vueStyle = { loader: 'vue-style-loader', options: { sourceMap: true } }
    const css = {
        loader: 'css-loader',
        options: {
            sourceMap: true,
            importLoaders: 2,
            exportOnlyLocals: false
        }
    }
    const postcss = {
        loader: 'postcss-loader',
        options: {
            parser: 'sugarss',
            sourceMap: true,
            plugins,
            order: 'presetEnvAndCssnanoLast'
        }
    }
    const cssModule = {
        ...css,
        options: {
            ...css.options,
            localIdentName: '[local]_[hash:base64:5]',
            modules: true,
        },
    }
    
    config.module.rules.push({
        test: /\.sss$/,
        oneOf: [
            { resourceQuery: /module/, use: [vueStyle, cssModule, postcss] },
            { use: [vueStyle, css, postcss] },
        ],
    })