Hi.
Is there a way ? Or is there any improvement planned to split the compiled code into many small .js files or Vue instances and to be able to use them later only for needy subpages to improve performance?
I mean we have many components and we mix them with normal blade files. For now when we want to use any we need to inject app.js file to this page. So if our app.js file is few MB or even more we need to get thie every time we change poge or smth. If we could only include part of components we need for actual page it could improve the performance of the application and make it work faster even when we are using it on lower cpu devices or something.
You're using Vue.js under a not-SPA page, which is totally valid, but you want the lazy-loading advantages of a SPA app.
I think you have one simple option, and is the Vue Lazy Loading guide. The other thing you could do is to extract the libraries to cache your libraries.
Finally, you could rewrite your app to have a single entry point entry-point.js with a Vue instance, an inside it, register the variable components declared on a const for each page:
app.net/js/components/login.jsconst PageComponent = ({
components: {
'validator': Validator
},
data: {
user: '',
password: '',
},
// ...
})
app.net/js/entry-point.jsnew Vue({
el: '#app'
components: {
'page-component': PageComponent
},
// ...
})
views/login.blade.php<head>
<script src="{{ mix('js/components/login.js') }}" defer></script>
<script src="{{ mix('js/entry-point.js') }}" defer></script>
<!-- ... -->
</head>
Using the latter, you would need to tell laravel-mix to compile every component by its own.
Other solutions would need a custom webpack configuration, or even a new build.
Do like below, it should work.
<template>
<div>
<sample-component></sample-component>
</div>
</template>
<script>
const SampleComponent = resolve => require(['./components/SampleComponent.vue'], resolve);
export default {
components:{
SampleComponent
}
}
</script>
Thanks for your replay :)
@lrembacz Did that work for you?
@Bowens20832 In webpack.mix.js:
// Config to make chunks
mix.webpackConfig({
plugins: [
// Clearing public/js file -> bug on laravel-mix when we using version and files are not removed
new Clean(['public/js/'], {verbose: false})
],
output: {
// Chunks in webpack
publicPath: '/',
chunkFilename: 'js/[name].[chunkhash].js',
},
});
And in components you should use async import for components:
Vue.component('my-component', () => import(/* webpackChunkName: "my-component" */ './MyComponent'));
const MyComponent= () => import(/* webpackChunkName: "my-component" */ './MyComponent')
const Vuetable = () => import(/* webpackChunkName: "vuetable" */ 'vuetable-2');
const Vuetable = (resolve) => import(/* webpackChunkName: "vuetable" */ 'vuetable-2').then( item => {
resolve(item.Vuetable)
});
And finaly you need to create .babelrc file with:
{
"plugins": ["syntax-dynamic-import"]
}
And install this as package with:
npm install babel-plugin-syntax-dynamic-import
Then recompile files with:
npm run dev
@lrembacz Thanks, Works perfect!
Is there some way to automatically create a legacy build so browsers like IE11 use that build?
I know Vue-cli 3.0.0 provides that option 'https://cli.vuejs.org/guide/browser-compatibility.html#modern-mode'. Here some more info: 'https://philipwalton.com/articles/deploying-es2015-code-in-production-today/'
@lrembacz Thanks.
Only one problem I see is that I have versioning enabled (mix.version()). Lazy loaded files does not get their version.
@muffeen Already a pull request for this. Waiting for merge. https://github.com/JeffreyWay/laravel-mix/pull/1557
Most helpful comment
@Bowens20832 In webpack.mix.js:
And in components you should use async import for components:
And finaly you need to create .babelrc file with:
And install this as package with:
npm install babel-plugin-syntax-dynamic-importThen recompile files with:
npm run dev