TLDR
How do you properly lazy load Vue components within a Laravel application, using Vue routing in addition to Laravel's own web routes?
Full story:
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:
- app.js
- router.js
- Test.vue
- app.blade.php
- home.blade.php
- news.blade.php
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.
app.js
import Vue from 'vue';
import router from './router.js';
new Vue({
el: '#app',
router
})
router.js
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',
});
Test.vue
<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>
app.blade.php
- Includes
<div id="app"></div>
within body
home.blade.php
- Includes
<router-view name="test"></router-view>
news.blade.php
- Also includes
<router-view name="test"></router-view>
, just to test.
Update 1:
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`)
}
Update 2:
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.
Update 3:
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. ????