laravel-mix: Tailwindcss2 @apply directive doesn't work inside vue component

  • Laravel Mix Version: “^6.0.6”
  • Node Version: 14.4.0
  • NPM Version: 6.14.5
  • OS: windows

I create a laravel application with jetstream and inertia-vue stack for my new project problem is Tailwindcs version 2 using postCss and it doesn’t support @apply directive inside vue components but inside .css file it works fine I don’t want that because that css file will load my every page I just want short inline utility classes with @apply directive but I can’t, How Can I achieve that.?

inside my vue template

<template>
 <div class="mt-4">
  <label for="hello">Hello</label>
  <input id="hello" class="input"/>
 </div>
</templete>

<style scoped>
    .input {
        @apply bg-gray-200 border h-10
    }
</style>

output inside browser like this

Capture

webpack.mix.js

const mix = require('laravel-mix');

mix.js('resources/js/app.js', 'public/js').vue()
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
        require('autoprefixer'),
    ])
    .webpackConfig(require('./webpack.config'));

if (mix.inProduction()) {
    mix.version();
}

webpack.config.js

const path = require('path');

module.exports = {
    resolve: {
        alias: {
            '@': path.resolve('resources/js'),
        },
    },
};

tailwind version : “^2.0.1”,

laravel version : 8.x,

jetstream version : 2.x,

inertiajs version: “^0.8.2”

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 8
  • Comments: 29 (1 by maintainers)

Most upvoted comments

The solution on the fresh install is as simple as putting a bare config file on the root of the project. Source.

// postcss.config.js
module.exports = {
    plugins: {
        tailwindcss: {},
        autoprefixer: {},
    },
}

A workaround that can temporarily solve this problem without using laravel-mix-tailwind:

In webpack.mix.js:

const mix = require('laravel-mix')

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel applications. By default, we are compiling the CSS
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.ts('resources/js/app.ts', 'public/js').vue()
  .postCss('resources/css/app.css', 'public/css')
  .webpackConfig(require('./webpack.config'))
  .sourceMaps()

if (mix.inProduction()) {
  mix.version()
}

In webpack.config.js:

const path = require('path')

module.exports = {
  resolve: {
    alias: {
      '@': path.resolve('resources/js')
    }
  },
  module: {
    rules: [
      {
        test: /\.(postcss)$/,
        use: [
          'vue-style-loader',
          { loader: 'css-loader', options: { importLoaders: 1 } },
          'postcss-loader'
        ]
      }
    ]
  }
}

In postcss.config.js:

module.exports = {
  plugins: [
    require('postcss-import'),
    require('tailwindcss')('./tailwind.config.js'),
    require('autoprefixer')
  ]
}

Now I can use:

<style lang="postcss">
.input-form {
  @apply block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50;
}
</style>

I got it working after installing laravel-mix-tailwind and using it this way in my webpack.config.js

require('laravel-mix-tailwind')

mix.postCss('resources/css/app.css', 'public/css', [
    require('tailwindcss')('./tailwind.config.js')
]).tailwind()

Style example in my vue file (notice the absence of the lang attribute:

<style>
.lookie {
    @apply bg-pink-100 text-pink-600 rounded-full border border-pink-400 mb-8;
}
</style>

So to sum up my experience:

  • can’t use lang="postcss" in style (webpack throws errors then) and therefore get linter errors when using long @apply with many classes
  • browserSync don’t reflect changes in vue component styles (yes, it recompiles “something” but no changes in the page)

I really expected that .vue().tailwind() will solve the issue…

Yeah this is something we need to look at. At the moment you have to specify the postCSS plugins globally for it to affect anything other than the specific css/sass/less/etc… file/tree you’ve given via mix.postCss / et al:

mix.options({
    postCss: [require("tailwindcss")("./tailwind.config.js")]
})

Note that you can set these plugins globally in your mix file like above and do not need to specify plugins via mix.postCss. You also have the option of using a postcss config file which we will honor as well.

@JeffreyWay What are your thoughts on this? Should we leave this as is or do you think it’d be reasonable to populate the PostCSS plugins globally from a single mix.postCss call. I’m on the fence about it.

after a thousand google searches, finally, I got the answer from here:

tq @nivv

require('laravel-mix-tailwind');

mix.js('resources/js/app.js', 'public/js').vue()
    .postCss('resources/css/app.css', 'public/css', [
        require('postcss-import'),
        require('tailwindcss'),
    ])
    .webpackConfig(require('./webpack.config'))
    .tailwind();

after applying @bebetoalves answer, I needed to remove the land="postcss" inside the vue style in order for it to work.

Can anyone tell finally what needs to be done to be able to use @apply directive inside a .vue file on the fresh Laravel 8 install? What plugins need to be installed? What needs to be added into config(s)? Should one use <style> or <style lang="postcss">? What else?

So now I have the use case of using postcss in a vue component like below:

<style lang="postcss">
.test {
    @apply bg-red-400; /*Not working */
}

.postcss-test {
    .working {
       background: red; /* Not working */
   }
}

I’ve also added this to my webpack config:

        rules: [
            {
                test: /\.postcss$/,
                use: [
                    'vue-style-loader',
                    'css-loader',
                    {
                        loader: 'postcss-loader'
                    }
                ]
            }
        ]

So basically I have to choose between tailwind or postcss, which is weird. I though @apply was parsed with postcss anyways?