How do you properly lazy load Vue components within a Laravel application, using Vue routing in addition to Laravel's own web routes?
I have a Laravel application that is using Vue. Now that the application has grown considerably in size, I would like to lazy load the Vue components.
To do this, I have set up these files:
If I import like: import Test from './components/Test';
, then everything works fine, but the component isn't lazy loaded.
If I import like
const Test = resolve => {
require.ensure(['./components/Test'], () => {
resolve(require('./components/Test'));
});
}
then, the component is lazy loaded. I can tell this because I am logging to the console. However, this seems to break all other JS and the CSS.
I can also see the new JS file created in the Network tab. It creates a 0.js file.
Based on this other question , I have also tried:
function loadView(view) {
return () => import(/* webpackChunkName: "[request]" */ `./components/${view}.vue`)
}
Everything works fine here as well, but the component isn't lazy loaded.
import Vue from 'vue';
import router from './router.js';
new Vue({
el: '#app',
router
})
import Vue from 'vue';
import Router from 'vue-router';
// import Test from './components/Test'; // Everything works, but doesn't lazy load
// Lazy loads and logs to the console, but breaks all of the other JS and the CSS
const Test = resolve => {
require.ensure(['./components/Test'], () => {
resolve(require('./components/Test'));
});
}
// Also tried this way, which works, but does not lazy load
// function loadView(view) {
// return () => import(/* webpackChunkName: "[request]" */ `./components/${view}.vue`)
// }
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
components: {
test: Test
// test: loadView('Test') //
}
},
{
path: '/news',
components: {}
}
],
mode: 'history',
});
<template>
<div>
<h1>This is a test</h1>
</div>
</template>
<script>
export default {
}
console.log('hey, this is from test.vue');
</script>
<style lang="scss" scoped>
</style>
<div id="app"></div>
within body<router-view name="test"></router-view>
<router-view name="test"></router-view>
, just to test. Based on this question: Lazy Loading Components not working with Vue Router , I have updated the loadView
function, but am still not able to load the CSS .
function loadView(view) {
return () => import(`./components/${view}.vue`)
}
Based on this question: vuejs lazy loading components without the router , I tried to import the component and set it to a constant:
const Test = () => import(
/* webpackChunkName: "./js/Test" */ './components/Test'
)
The lazy loading works perfectly, but the CSS still doesn't load.
When using import Test from './components/Test';
, I notice that the app.css file is compiled successfully to 560 KiB.
However, when using const Test = () => import(/* webpackChunkName: "./js/Test" */ './components/Test');
, this same file fails to compile, and instead remains at 0 bytes.
The problem here was with Webpack and not the Vue router. The routing was working fine, but as noted in Update 3, the app.css would compile to 0 bytes.
I noticed that this was a common problem that others had as well. The best solution that I found comes from a comment by Daljeet Singh, aka Ilamp, here: https://github.com/JeffreyWay/laravel-mix/issues/1914#issuecomment-628791041
To save you a click, here is what he did:
npm install laravel-mix-merge-manifest --save-dev
const mix = require('laravel-mix');
require('laravel-mix-merge-manifest');
mix.sass('resources/sass/app.scss', 'public/css')
.version();
if (!mix.inProduction()) {
mix.sourceMaps();
}
mix.mergeManifest();
const mix = require('laravel-mix');
require('laravel-mix-merge-manifest');
mix.react('resources/js/app.js', 'public/js')
.extract([])
.setPublicPath('public')
.version();
if (!mix.inProduction()) {
mix.sourceMaps();
}
mix.mergeManifest();
"dev": "npm run development-js && npm run development-css",
"development-js": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.js.mix",
"development-css": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.css.mix",
"prod": "npm run production-js && npm run production-css",
"production-js": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.js.mix",
"production-css": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js --env.mixfile=webpack.css.mix",
"watch": "npm run development-js -- --watch & npm run development-css -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
Happy coding
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.