Laravel-mix: extractVueStyles doesn't work with dynamically imported components in a single chunk

Created on 15 Apr 2019  路  3Comments  路  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version: 4.0.15 (npm list --depth=0)
  • Node Version (node -v): 10.15.3
  • NPM Version (npm -v): 6.4.1
  • OS: Ubuntu 18.04

Description:

I've got an existing multi-page app that I'm adding Vue components into, so I'm rendering individual components on the server and rehydrating them individually. This works great, except dynamically imported components' styles don't load until their scripts do. I'd like to solve this by extracting all the components' CSS into one file, taking a minor one-time hit in load time there in exchange for faster page render time.

Steps To Reproduce:

I've stubbed out a minimal repo demonstrating how I'd like to set this up: https://github.com/brian-c/laravel-mix-vue-component-ssr

There are two separate webpack builds going on, both have extractVueStyles: 'components.css' set:

  • There's a single-chunk (using the LimitChunkCountPlugin) build of _just_ the components (src/components.js). The server uses this to replace ~~~{ component, props }~~~ syntax in index.html with rendered component markup (this is done way more robustly in real life). No components.css file is output.

  • The browser build's entry is pretty normal. It' entry is src/main.js. A components.css file is created, but it's empty.

I can justify the browser build's CSS not being extracted--those components are loaded dynamically, so their CSS probably should be too.

The single-file build for the server has everything in one chunk, so splitting out its CSS makes more sense.

All 3 comments

Dynamic imports aren't supported in Mix 4. We're on hold until webpack 5 is out.

Dynamic imports aren't supported in Mix 4. We're on hold until webpack 5 is out.

That's not correct, it is working when you import your scss described like here:

https://github.com/JeffreyWay/laravel-mix/issues/2228#issuecomment-538719797

Another option to get t working is to use a kind of this in package.json and webpack.mix.js:

"hot": "cross-env HMR=1 NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --https --config=node_modules/laravel-mix/setup/webpack.config.js",

and webpack.mix.js

const cssImport = require('postcss-import')
const cssNesting = require('postcss-nesting')
const mix = require('laravel-mix')
const path = require('path')
const tailwindcss = require('tailwindcss')
require('laravel-mix-purgecss')
/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js').webpackConfig({
    output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.runtime.esm.js',
            '@': path.resolve('resources/js'),
        },
    },
})
    .babelConfig({
        plugins: ['@babel/plugin-syntax-dynamic-import'],
    })
    .version()
    .sourceMaps()

if (!process.env.HMR) {
    mix.postCss('resources/css/app.css', 'public/css', [
        cssImport(),
        cssNesting(),
        tailwindcss('tailwind.js'),
    ]);

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

} else {
    console.log('CSS IS NOT COMPILED IN HMR MODE :');
}

Dynamic imports aren't supported in Mix 4. We're on hold until webpack 5 is out.

That's not correct, it is working when you import your scss described like here:

#2228 (comment)

Another option to get t working is to use a kind of this in package.json and webpack.mix.js:

"hot": "cross-env HMR=1 NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --https --config=node_modules/laravel-mix/setup/webpack.config.js",

and webpack.mix.js

const cssImport = require('postcss-import')
const cssNesting = require('postcss-nesting')
const mix = require('laravel-mix')
const path = require('path')
const tailwindcss = require('tailwindcss')
require('laravel-mix-purgecss')
/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js').webpackConfig({
    output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.runtime.esm.js',
            '@': path.resolve('resources/js'),
        },
    },
})
    .babelConfig({
        plugins: ['@babel/plugin-syntax-dynamic-import'],
    })
    .version()
    .sourceMaps()

if (!process.env.HMR) {
    mix.postCss('resources/css/app.css', 'public/css', [
        cssImport(),
        cssNesting(),
        tailwindcss('tailwind.js'),
    ]);

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

} else {
    console.log('CSS IS NOT COMPILED IN HMR MODE :');
}

perfect answer 馃憣

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wendt88 picture wendt88  路  3Comments

rderimay picture rderimay  路  3Comments

terion-name picture terion-name  路  3Comments

hasnatbabur picture hasnatbabur  路  3Comments

Bomavi picture Bomavi  路  3Comments