0

I'm working on a Laravel + Vue SPA project and I tried to optimize the project with code splitting and defining lazy routes, but now every lazy route file are not being versioned.

Let's see if I can describe the problem.

enter image description here

You can see here the main files are versioned: app.css, app.js, vendors.js. But what happens with users.js? It's a lazy route.

app.blade.php

<!doctype html>
<html lang="ca_ES">
<head>
    <link rel="manifest" href="/fullscreen-manifest.json">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <link rel="shortcut icon" href="{{ asset('favicon.png') }}">
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href='https://fonts.googleapis.com/css?family=Roboto:100,300,500,700,900|Material+Icons' rel="stylesheet">
    <link href="{{ mix('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<script src="{{ mix('js/app.js') }}" defer></script>
<script src="{{ mix('vendors.js') }}" defer></script>
</body>
</html>

routes.js

const home = () => import(/* webpackChunkName: "home" */ '@/pages/home');
const login = () => import(/* webpackChunkName: "home" */ '@/pages/auth/login');
const pageNotFound = () => import(/* webpackChunkName: "home" */ '@/pages/errors/404');
const pageForbidden = () => import(/* webpackChunkName: "home" */ '@/pages/errors/403');

import users from "./users";
import profile from "./profile";
(...)

export default [
    ...users,
    ...profile,
    (...)
    {
        path: '/',
        name: 'home',
        component: home,
        meta: {
            auth: true,
        }
    },
    {
        path: '/forbidden',
        name: '403',
        component: pageForbidden,
        meta: {
            auth: true,
        }
    },
    {
        path: '/login',
        name: 'login',
        component: login,
        meta: {
            guest: true,
        }
    },
    {
        path: '*',
        name: '404',
        component: pageNotFound,
    }
];

users.js

const users = () => import(/* webpackChunkName: "users" */ '@/pages/users/index');
const show = () => import(/* webpackChunkName: "users" */ '@/pages/users/show');

export default [
    {
        path: '/users',
        name: 'users',
        component: users,
        meta: {
            auth: true,
            admin: true,
        }
    },
    {
        path: '/show/:id',
        name: 'users.show',
        component: show,
        meta: {
            auth: true,
            admin: true,
        }
    },
];

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CompressionPlugin = require('compression-webpack-plugin');
const moment = require('moment');

module.exports = {
    output: {
        chunkFilename: '[name].js',
    },
    resolve: {
        extensions: ['.js', '.json', '.vue'],
        alias: {
            '@': path.join(__dirname, './resources/js'),
        }
    },
    plugins: [
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
        new BundleAnalyzerPlugin({
            analyzerMode: 'static',
            openAnalyzer: false,
            reportFilename: 'bundle-analyzer-plugin/reports/' + moment().format('YYYYMMDD') + '.html'
        }),
        new CompressionPlugin({
            filename: '[path].gz[query]',
            algorithm: 'gzip',
            test: /\.js$|\.css$|\.html$/,
            threshold: 10240,
            minRatio: 0.7
        }),
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: 'vendors',
                    chunks: 'all'
                }
            }
        }
    }
};

webpack.mix.js

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

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

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

mix.webpackConfig(config);

So what am I doing wrong? I can import all lazy routes files on the app.blade.php and it would be importing with versioning, but I will be missing the point... The idea is this files are being include when the websites need them. But when they do that automatically it does without versioning.

4
  • can you put your route.js or router file Commented Nov 17, 2020 at 7:27
  • Updated, you can see I'm using a lot of files for better structure. Commented Nov 17, 2020 at 7:34
  • Have you tried appending your version to chunkFilename like chunkFilename: '[name].js?t=' + new Date().getTime()? Commented Nov 17, 2020 at 7:43
  • Then the problem is on app.blade.php I cannot import vendors.js. Unable to locate Mix file: /vendors.js. (View: /var/www/html/resources/views/app.blade.php). And I think it's unappropiated adding the time suffix on importing the file. Commented Nov 17, 2020 at 7:54

1 Answer 1

0

as you are using Vue Router so you should use Dynamic Imports like this


export default [
    {
        path: '/users',
        name: 'users',
        component: () => import('@/pages/users/index'),
        meta: {
            auth: true,
            admin: true,
        }
    },
    {
        path: '/show/:id',
        name: 'users.show',
        component: import('@/pages/users/show'),
        meta: {
            auth: true,
            admin: true,
        }
    },
];

ref link https://laravel-news.com/using-dynamic-imports-with-laravel-mix

Sign up to request clarification or add additional context in comments.

2 Comments

You wrote both routes different. I understand the first is the correct. But this is exactly what I'm doing... watch the first lines on users.js. const users = () => import(/* webpackChunkName: "users" */ '@/pages/users/index');
in vue router don't use const inside component you can use const dynamic import for more details read that ref link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.