使用 webpack
非 Vite
在 laravel
上開發 Vue
時,往往會將所有組件都註冊在 app.js
上,這樣在加載時會一次載入所有組件,導致 client side
網頁加載時間變長,影響使用者體驗。
從 laravel-mix(4.0.16)
開始,開始支援動態引入 (Dynamic Import)
。動態引入是一種 code splitting
,可以將單一的 bundle
切分成多個塊 chunk
,可搭配平行載入或在需要時才載入,或是對一些不常變動的 chunk
個別做快取,以達到載入效能的優化。這是 Lazy Loading
(等用到的時候再載入)的一種實現。
可以選擇設定webpack.mix.js
或.babelrc
檔案擇一即可
在webpack.mix.js
加上以下這行程式碼,laravel-mix
必須是4.0.16
版本以上
mix.babelConfig({ plugins: ['@babel/plugin-syntax-dynamic-import'], });
根目錄新增.babelrc
檔案或是修改,將 @babel/plugin-syntax-dynamic-import
加到 「plugins」
這個array
裏面,在啟用laravel-mix
時就會自動引入
{ "plugins": [ "@babel/plugin-syntax-dynamic-import" ] }
原先引入Vue組件是使用static import
方法引入
import ExampleComponent from "./components/ExampleComponent.vue";
Vue.component("example-component", ExampleComponent);
將其更改為Dynamic Import
通過使用特殊註釋語法提供塊名稱來使用命名塊(需要 webpack > 2.4
),加入/* webpackChunkName: "example" */
,為塊命名,不然在run dev
跟 run prod
檔案名稱會不相同。
const ExampleComponent = () => import(/* webpackChunkName: "example" */ "./components/ExampleComponent.vue");
Vue.component("example-component", ExampleComponent);
Vue.component("example-component", () => import(/* webpackChunkName: "example" */ "./components/ExampleComponent.vue"));
vue router
中
const routes = [
{
path:"/home",
component: ()=>import(/* webpackChunkName: "example" */ './components/ExampleComponent'),
},
];
可以設置webpack.mix.js
更改塊(chunks)
存放的位置
mix.webpackConfig({
output:{
chunkFilename: 'js/chunks/[name].js',
publicPath: '/',
}
});
npm run dev
或是 npm run watch
可以看到在還未分割檔案前app.js
的容量較大,分割後多了其他組件的js
而app.js
也縮水了
切割前:
切割後:
也只需要加載app.js
,laravel-mix
會去解決按需要才載入問題
Page vue
修改app.js
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
const app = createInertiaApp({
title: (title) => `${title} - ${appName}`,
// 原先寫法
// resolve: (name) => require(`./Pages/${name}.vue`),
// 更改後
resolve: (name) => import(/* webpackChunkName: "[request]" */`./Pages/${name}.vue`),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.mount(el);
},
});
前
後