Lazy Load Routes in Vue mit dynamischen Webpack-Kommentaren

Avatar of Jorge Baumann
Jorge Baumann am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die Funktionsweise von Routing in JavaScript besteht normalerweise darin, dass Sie angeben, welches relative URL-Muster Sie für welche Komponente haben möchten. Also für /about möchten Sie, dass die Komponente <About /> gerendert wird. Schauen wir uns an, wie man das in Vue/Vue Router mit Lazy Loading macht und das so sauber wie möglich. Ich verwende diesen kleinen Tipp ständig in meiner eigenen Arbeit.

Ein Repository, das alles enthält, was in diesem Beitrag behandelt wird, ist auf GitHub verfügbar.

Wahrscheinlich haben Sie Vue-Routen (URLs) wie diese gesehen

import Vue from 'vue'
import VueRouter from 'vue-router'

import Home from '../views/Home.vue'
import About from '../views/About.vue'
import Login from '../views/Login.vue'

Vue.use(VueRouter)

const routes = [
  { path: '/', name: 'Home', component: Home },
  { path: '/about', name: 'About', component: About },
  { path: '/login', name: 'Login', component: Login }
]

const router = new VueRouter({
  routes
})

export default router

Das lädt die Komponente <Home /> an der Route /, die Komponente <About /> an der Route /about und die Komponente <Login /> an der Route /login.

Das ist aber keine gute Code-Splitting-Methode, da alle drei Komponenten zusammen gebündelt werden, anstatt dynamisch nach Bedarf geladen zu werden.

This is a terminal screenshot with a dark purple background with text in white green and blue. The content shows the final build after compiling.

Hier ist eine andere Möglichkeit, dasselbe zu tun, nur mit Code-Splitting mit dynamischen Import-Anweisungen und Webpack-Chunk-Namen

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import(/* webpackChunkName: "Home" */ '../views/Home.vue')
  },
  {
    path: '/about',
    name: 'About',
    component: () => import(/* webpackChunkName: "About" */ '../views/About.vue')
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import(/* webpackChunkName: "Login" */ '../views/Login.vue')
  }
]

Das ist vollkommen in Ordnung und hat keine größeren Nachteile, außer dass es etwas umständlich und repetitiv ist. Da wir großartige Entwickler sind, machen wir eine kleine Abstraktion, die uns hilft, indem wir ein Array verwenden, das wir mit .map durchlaufen.

const routeOptions = [
  { path: '/', name: 'Home' },
  { path: '/about', name: 'About' },
  { path: '/login', name: 'Login' }
]

const routes = routeOptions.map(route => {
  return {
    ...route,
    component: () => import(`@/views/${route.name}.vue`)
  }
})

const router = new VueRouter({
  routes
})

Jetzt haben wir die Verwendung des component-Schlüssels reduziert, indem wir den Routenname als Parameter in der import-Funktion verwenden.

Aber was passiert, wenn wir den Chunk-Namen festlegen wollen?

Soweit ich weiß, können Sie keine dynamischen Kommentare in JavaScript ohne eine Art Build-Schritt haben. Wir opfern also Kommentare (webpackChunkName) zugunsten von weniger Code, den wir in diesem Fall schreiben müssen. Es liegt ganz bei Ihnen, was Sie bevorzugen.

Nur ein Scherz, wir beheben das.

Seit webpack 2.6.0 werden die Platzhalter [index] und [request] unterstützt, was bedeutet, dass wir den Namen des generierten Chunks wie folgt festlegen können

// ...

const routeOptions = [
  { path: '/', name: 'Home' },
  { path: '/about', name: 'About' },
  { path: '/login', name: 'Login' }
]

const routes = routeOptions.map(route => {
  return {
    ...route,
    component: () => import(/* webpackChunkName: "[request]" */ `../views/${route.name}.vue`)
  }
})

const router = new VueRouter({
  routes
})

Schön! Jetzt haben wir die volle Leistung, plus dynamisch geladene Routen mit benannten Chunks. Und es funktioniert mit Vue 2 und Vue 3. Sie können es ausprobieren, indem Sie npm run build im Terminal ausführen

This is the same terminal screenshot as before, but with three of the JavaScript built files highlighted with the words "Named Chunks" annotated beside them.
Sehen Sie das? Jetzt sind die Komponenten in Chunks aufgeteilt… und der Build hat die ganze Benennung für uns übernommen!

Aber wir können das noch einen Schritt weiter gehen, indem wir die Lazy-Loaded-Routen in benannte Chunks gruppieren, anstatt einzelne Komponenten. Zum Beispiel können wir Gruppen erstellen, die unsere wichtigsten Komponenten zusammenfassen und den Rest in einer anderen "nicht so wichtigen" Gruppe. Wir aktualisieren lediglich den Webpack-Chunk-Namen anstelle des Platzhalters [request], den wir zuvor verwendet haben

const routes = [
  {
    path: "/",
    name: "Home",
    component: () =>
      import(/* webpackChunkName: "VeryImportantThings" */ "../views/Home.vue")
  },
  {
    path: "/about",
    name: "About",
    component: () =>
      import(/* webpackChunkName: "VeryImportantThings" */ "../views/About.vue")
  },
  {
    path: "/login",
    name: "Login",
    component: () =>
      import(/* webpackChunkName: "NotSoImportant" */ "../views/Login.vue")
  },
  {
    path: "/contact",
    name: "Contact",
    component: () =>
      import(/* webpackChunkName: "NotSoImportant" */ "../views/Contact.vue")
  }
];

Jetzt sind unsere vier Komponenten in zwei separate Chunks gruppiert.

The same terminal with different compiled JavaScript files.

Da haben Sie es! Eine Technik für Lazy Loading von Routen in Vue, plus einige Ideen, wie Sie diese beim Build benennen und gruppieren können.