Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@apply doesn't work with Laravel Mix #53

Closed
HapLifeMan opened this issue Nov 2, 2017 · 12 comments
Closed

@apply doesn't work with Laravel Mix #53

HapLifeMan opened this issue Nov 2, 2017 · 12 comments

Comments

@HapLifeMan
Copy link
Contributor

Hey,

Everything works fine until I decided to use components as it's said in the documentation.

Compiling failed :

 ERROR  Failed to compile with 2 errors                                                                                                                                                                                                                                                                                                               12:41:50 PM

 error  in ./resources/assets/sass/app.css

Module build failed: ModuleBuildError: Module build failed: Syntax Error 

(2:3) No .text-white class found.

  1 | .btn {
> 2 |   @apply .text-white;
    |   ^
  3 | }
  4 | 

    at runLoaders (/Users/thomas/Sites/cdsud/www/node_modules/webpack/lib/NormalModule.js:195:19)
    at /Users/thomas/Sites/cdsud/www/node_modules/loader-runner/lib/LoaderRunner.js:364:11
    at /Users/thomas/Sites/cdsud/www/node_modules/loader-runner/lib/LoaderRunner.js:230:18
    at context.callback (/Users/thomas/Sites/cdsud/www/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at Promise.resolve.then.then.catch (/Users/thomas/Sites/cdsud/www/node_modules/postcss-loader/lib/index.js:185:44)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

 @ multi ./node_modules/laravel-mix/src/builder/mock-entry.js ./resources/assets/sass/app.css

 error  in ./resources/assets/sass/app.css

Module build failed: ModuleBuildError: Module build failed: Syntax Error 

(2:3) No .text-white class found.

  1 | .btn {
> 2 |   @apply .text-white;
    |   ^
  3 | }
  4 | 

    at runLoaders (/Users/thomas/Sites/cdsud/www/node_modules/webpack/lib/NormalModule.js:195:19)
    at /Users/thomas/Sites/cdsud/www/node_modules/loader-runner/lib/LoaderRunner.js:364:11
    at /Users/thomas/Sites/cdsud/www/node_modules/loader-runner/lib/LoaderRunner.js:230:18
    at context.callback (/Users/thomas/Sites/cdsud/www/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at Promise.resolve.then.then.catch (/Users/thomas/Sites/cdsud/www/node_modules/postcss-loader/lib/index.js:185:44)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

My wepback.mix.js :

let mix      = require('laravel-mix');
let tailwind = require('tailwindcss');
mix.postCss('./resources/assets/sass/app.css', './public/css/main.css', [tailwind('./tailwind.js')]).disableNotifications();

... and app.css:

@tailwind preflight;

@import "./components/buttons.css";

@tailwind utilities;

@import './main.css';
@import './admin.css';

What's wrong? :/

@adamwathan
Copy link
Member

Can you share a public repo that reproduces this? I would expect a different error since @import doesn't inline imports in normal CSS and is also required to be the first statement in a file.

Are you using CSS here or Sass?

@HapLifeMan
Copy link
Contributor Author

HapLifeMan commented Nov 2, 2017

Here's the repo: https://github.com/HapLifeMan/apply-css-not-working and I'm using CSS!

@adamwathan
Copy link
Member

adamwathan commented Nov 2, 2017

Ah ok I've reproduced this now.

The issue is that @import doesn't work the same way in normal CSS as it does in Sass or Less. Mix seems to be trying to process your buttons.css file with Tailwind independently, and it can't find any of the other classes because they aren't in the same file.

There's a couple ways to work around this:

  1. Use Less just for it's import functionality. Your mix file would look like this then:

    mix.less('./resources/assets/less/app.less', './public/css/main.css')
        .options({ postCss: [ tailwind('./tailwind.js')]})
        .disableNotifications()

    You can even keep your other files as plain CSS files and import them like this:

    @tailwind preflight;
    
    @import (inline) "./components/buttons.css";
    
    @tailwind utilities;
    
    @import (inline) './main.css';
    @import (inline) './admin.css';
  2. Use the postcss-import plugin to inline your imports. I would probably lean towards this option if you want to stay away from existing preprocessors and just use Tailwind with raw CSS.

    There's one gotcha with this plugin which is that it's very strict about the CSS spec and the CSS spec says that @import rules have to come first in a file, which means you can't have @tailwind preflight come before an @import rule.

    The way to get around that is to move your Tailwind calls to their own files, and make your main CSS file just imports:

    @import "./tailwind-preflight.css";
    
    @import "./components/buttons.css";
    
    @import "./tailwind-utilities.css";
    
    @import "./main.css";
    @import "./admin.css";

    tailwind-preflight.css would just look like this:

    @tailwind preflight;
    

    ...and tailwind-utilities.css would just look like this:

    @tailwind utilities;
    

    To use the import plugin, add it to the beginning of your PostCSS plugin chain:

    let mix      = require('laravel-mix');
    let tailwind = require('tailwindcss');
    let postcssImport = require('postcss-import');
    
    mix.less('./resources/assets/css/app.css', './public/css/main.css', [
        postcssImport(),
        tailwind('./tailwind.js'),
    ])
    .disableNotifications();

Let me know if that fixes your issue! We'll definitely have to add some more documentation about this.

@HapLifeMan
Copy link
Contributor Author

Bug fixed! Thank you ❤️
I can now move on serious stuff 😈

@mkarnicki
Copy link
Contributor

I have quite large webpack.mix.js - for anyone that finds this issue, it might be helpful to know:

If you have any weird problems (like your css file being literally copied and not processed) you should put that last snippet (excluding the first line) somewhere at the end of the webpack.mix.js. This did the trick for me.

@onetrev
Copy link

onetrev commented Jan 18, 2018

Hey @adamwathan, just noticed I think you have a minor mistake in your tip for postcss-import.

You have tailwind-utilities.css as having @tailwind preflight; when it should be @tailwind utilities; right?

@adamwathan
Copy link
Member

Good catch, fixed!

@jcush
Copy link

jcush commented Mar 15, 2020

@adamwathan I've tried using your postcss-import method but am still getting the same issue about "missing '}'" when trying to build using @apply.

webpack.mix.js

let mix = require('laravel-mix');
let tailwindcss = require( 'tailwindcss' );

let dirs = {
	src: {
		js: 'src/js/',
		scss: 'src/scss/'
	},
	dist: {
		js: 'web/js/',
		css: 'web/css/'
	}
}

mix.js( dirs.src.js + 'main.js', dirs.dist.js )
.sass( dirs.src.scss + 'tailwind.scss', dirs.dist.css ).options({
	postCss: [ tailwindcss('tailwind.config.js') ]
})
.sass( dirs.src.scss + 'style.scss', dirs.dist.css, [
	portcssImport(),
	tailwind()
])

tailwind.scss

@tailwind base;
@tailwind components;
@tailwind utilities;

body{
	/* This comment solves Mix's issue with needing an SCSS file with at least one non-empty ruleset */
}

style.scss

html{
	font-size: 20px;
}
body{
	padding:
		env( safe-area-inset-top, 0 )
		env( safe-area-inset-right, 0 )
		env( safe-area-inset-bottom, 0 )
		env( safe-area-inset-left, 0 );

	font-weight: 200;
}

.plate{
	@apply bg-gray-900 text-white p-4;
}

To confirm, if I remove the @apply declaration then everything works fine...

@adamwathan
Copy link
Member

Can you create a public GitHub repo that reproduces the issue? I can play with it and figure it out much faster that way than having to recreate it all from scratch myself.

@jcush
Copy link

jcush commented Mar 25, 2020

tw-bug-example.zip

I tried creating a public GitLab repo but couldn't push to it for some reason... so I've attached a zip here. I removed all sensitive info, node modules and composer packages. It's a Craft CMS site

@thamerbelfkihthamer
Copy link

@adamwathan have you found what the problem with @jcush problem, please? I'm facing the same problem here.

@jcush
Copy link

jcush commented Apr 10, 2020

@thamerbelfkihthamer I haven't tried this yet, but just re-reading the issue I think in the meantime while we let @adamwathan dig into it it could be an idea to create a separate stylesheet for utilities created by applying tailwind classes, then less that one and sass the others. So you'd do all your @apply calls in one sheet, which would use less, then put the rest of your styles in sass.

In the nicest way possible without any offence meant to Tailwind or Adam (big Refactoring UI fan here) I'm currently customising Bootstrap 4 for theming instead. I just have more experience with it personally and wanted to crack on with the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants