inyansuta's avatar

Async Vue component breaks sass compilation

This code works fine and in public folder generate successfuly js and css files.

// webpack.mix.js
const mix = require('laravel-mix');

require('laravel-mix-tailwind');

mix
    .sass('resources/sass/app.scss', 'public/css')
    .sass('resources/sass/tailwind.scss', 'public/css')
    .tailwind();

mix
    .js('resources/js/bootstrap.js', 'public/js')
    .js('resources/js/app.js', 'public/js');

But when I add import async vue component to app.js file:

Vue.component('async-component', () => import('./components/async/AsyncComponent'));

the sass compilation generate in public folder EMPTY CSS FILES !!.

Oddly enough, if I run "npm run dev" twice (I comment on compiling javascript and leave only sass, then I comment on sass and leave only js), all files are generated correctly. But both together generate successfuly only js file, the css files are empty. When I dont import async components, all is fine as expected....

What am I doing wrong?

0 likes
5 replies
ajithlal's avatar

why you are using two mix try chaining it to one like

// webpack.mix.js
const mix = require('laravel-mix');

require('laravel-mix-tailwind');

mix
    .js('resources/js/bootstrap.js', 'public/js')
    .js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css')
    .sass('resources/sass/tailwind.scss', 'public/css')
    .tailwind();

If this not solve your problem. Show us your app.js file.

inyansuta's avatar

@ajithlal Thank you for your answer.

The problem is not in my scripts. After three hours I identified what causes the problem of not generating css. Here's an example.

Create new Laravel project, install npm and Vue Library.

laravel new test_project

npm install

npm install vue --save-dev

Create AsyncComponent.vue file.

// resources/js/AsyncComponent.vue
<template>
    <div>
        Async Component.
    </div>
</template>

<script>
    export default {
        name: 'AsyncComponent',
    }
</script>

Update app.js file.

// resources/js/app.js
require('./bootstrap');

import Vue from 'vue';

Vue.component('async-component', function() { import('./AsyncComponent') });

Update app.scss file.

// resources/sass/app.scss
h1 {
    display: block;
}

Start npm run dev

npm run dev

Everything is fine in this step.

// public/css/app.css has 26 bytes
// public/js/app.js has 921 KiB
// public/0.js (async component) has 10.3 KiB

Now try create separate js file - another.js

// resources/js/another.js

// some content

Add this file to webpack.min.js

// webpack.min.js
mix.js('resources/js/app.js', 'public/js')
    .js('resources/js/another.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

Start npm run dev

npm run dev

Everything is fine in this step (public/css/app.css has 26 bytes)

But, when you try toggle files in webpack.min.js (first is another.js and second app.js with async component), app.css file in public folder is empty (0 bytes).

// webpack.min.js
mix.js('resources/js/another.js', 'public/js') // another.js as first
    .js('resources/js/app.js', 'public/js') // app.js as second
    .sass('resources/sass/app.scss', 'public/css');

Start npm run dev

npm run dev

Now generates css file in public/css/app.css is empty. Why?

This mystery of generating empty css files is somehow related to importing an asynchronous component in app.js. Once I comment line with async component import:

// resources/js/app.js
require('./bootstrap');

import Vue from 'vue';

// Vue.component('async-component', function() { import('./AsyncComponent') });

the css file is generated correctly.

Importing a single js file in the webpack.min.js file works fine, but I want to generate at least two javascript files and load them separately in html (app.js and bootstrap.js), but I get a css error.

Why does this error occur and how to work around it?

ajithlal's avatar

@inyansuta rewrite your component initializing from

Vue.component('async-component', function() { import('./AsyncComponent') });

to

Vue.component('async-component', require('./AsyncComponent.vue'));

and compile again.

inyansuta's avatar

@ajithlal Of course, your code works, but it does not generate the asynchronous component.

ajithlal's avatar

@inyansuta i'm not sure but, Just remove the name from the export defaut section on your script and compile like below.

<template>
    <div>
        Async Component.
    </div>
</template>

<script>
    export default {
   
    }
</script>

Please or to participate in this conversation.