3 tips voor het schalen van grote Vue.js-applicaties

Tip #1:Denkmodule!

De bestandsarchitectuur gegeven door vue-cli is geweldig. Maar na 3-4 pagina's beginnen uw bestanden te zwaar te worden.
U komt misschien in de verleiding om uw componenten in meerdere mappen te plaatsen. Maar nogmaals, na 10 pagina's krijgt u weer met hetzelfde probleem te maken.

Het idee is om uw aanvraag op te splitsen in begrippen. Blijf bij één uniek woord.
In een winkeltoepassing kunnen we bijvoorbeeld Catalogus . krijgen , Mandje en Betaling . nutsvoorzieningen

├─ src/
│  ├─ core/
│  ├─ modules/
│  │  ├─ Catalog/
│  │  │  ├─ Components/
│  │  │  ├─ Pages/
│  │  │  ├─ Routes/
│  │  │  ├─ Services/
│  │  │  │  ├─ catalog.api.js
│  │  │  │  └─ catalog.services.js
│  │  │  ├─ Store/
│  │  │  │  ├─ catalog.action.js
│  │  │  │  └─ catalog.getters.js
│  │  │  │  └─ catalog.mutationTypes.js
│  │  │  │  └─ catalog.state.js
│  │  │  │  └─ index.js
│  │  │  ├─ Tests/
│  │  │  ├─ Catalog.vue

Enkele belangrijke dingen hier:

Isolatie

Om een ​​goede isolatie te behouden, mogen modules er niet tussen staan. Wat ik bedoel is, Module A mag een component niet delen met Module B . Voor algemene functionaliteiten (d.w.z. gebruiker ingelogd, gebruikerstaal...) , je hebt de core map!

Slimme versus domme componenten

Het is belangrijk om een ​​scheiding te bewaren tussen uw slimme componenten (Pages map) uit de domme (Components map). In een notendop:

  • slimme componenten:hebben toegang tot de winkel, router, raamobject...
  • domme componenten:rekwisieten nemen, evenementen uitzenden. Dat is het!

De belangrijkste voordelen van deze aanpak zijn herbruikbaarheid, een betere scheiding van zorgen...

Splitsen, splitsen, splitsen!

Als je component te groot wordt, wees dan niet verlegen:splits het! In de handleiding van Vue.js wordt de regel "Sterk gekoppelde componentnamen" beschouwd als sterk aanbevolen.

// 👎 Bad
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue

// 👍 Good
|- CatalogList.vue
|- CatalogListItem.vue
|- CatalogListItemButton.vue

Isoleer ook stijlen!

Onthoud:Global CSS is slecht . Vermijd ze zoveel als je kunt!

  • .vue bestanden:de gemakkelijkere quick win daarvoor is het gebruik van het scoped attribuut in de stijltag:<styles scoped>
  • Geen grote fan van .vue bestanden? (als u meerdere kleine componenten wilt maken zonder tientallen bestanden te maken). Overweeg bibliotheken zoals 💅 vue-styled-componenten. De stijlinkapseling werkt als een tierelier!
  import styled from 'vue-styled-components';

  const StyledTitle = styled.h1`
      font-size: 1.5em;
      text-align: center;
      color: palevioletred;
  `;

  <StyledTitle>Cool title</StyledTitle>

Testen

Het testen van applicaties is een zeer complex onderwerp, dat een hele blogpost verdient. Laten we, om het simpel te houden, de vorige bestandsarchitectuur nemen en kijken wat we moeten testen en hoe we het moeten doen.

  • Componenten:lage prioriteit, gemakkelijk te doen. schrijf unit tests voor elk onderdeel. het moet gemakkelijk te doen zijn.
  • Pagina's:hoge prioriteit, moeilijk te doen. Je zult waarschijnlijk moeten spotten met api/browser-onderdelen.
  • Routes:meestal zijn er geen bugs. Laat het staan ​​voor E2E-tests.
  • Diensten:
    • api-interface:persoonlijk test ik dit deel niet (90% van de code wordt bespot).
    • helpers/dataFormaters:Hoge prioriteit, makkelijk te doen. Meestal de gemakkelijkste tests om in je app te doen!
  • Opslaan:het moeilijkste onderdeel om te testen. Je kunt het testen via integratietesten. Het afzonderlijk testen van actie, getter en initiële status is nutteloos.

💡 Lazy laad je modules!

Overweeg om uw modules lui te laden om de JavaScript-bundel te verminderen!

export default new Router({
  routes: [
    {
      path: '/catalog',
      name: 'catalog',
      component: () => import(/* webpackChunkName: "catalog" */ './modules/Catalog/views/Catalog.vue')
    },
    // ...
  ]
})

Als je dit al hebt gedaan en je vindt je app nog steeds te groot, overweeg dan de volgende tip.

Tip #2:Overweeg micro-frontends

In de afgelopen jaren was microservices-architectuur behoorlijk trendy geworden. Veel bedrijven splitsten hun eenvoudige oude monoliet-backend op in een heleboel kleine services op de backend.

Tegenwoordig lijkt het erop dat sommige bedrijven dit backend-paradigma naar de frontend-wereld hadden gekopieerd. De belofte is vrij gelijkaardig aan de backend:splits grote monoliet in meerdere applicaties, schaal en in staat zijn om applicatie te schrijven met verschillende technologieën. Ja. Je leest de laatste zin goed. U kunt de betaalapplicatie in Vue schrijven en de Catalogusapplicatie in React.

Indien nodig kunnen verschillende applicaties met elkaar praten via gebeurtenissen die zijn geregistreerd op het vensterobject (waarnemer publiceren/abonneren).

⚠️ Maar ik geef je een waarschuwing. Er is geen wondermiddel. Als je een paradigma verlaat voor een ander, kom je niet van de problemen af. Je vervangt ze.

👍 Voordelen:volledige isolatie

Als de backend ook microservicegericht is, kunnen teams in silo's werken. Ze beheren hun domein van begin tot eind.

👍 Voordelen:mogelijkheid om verschillende frameworks / verschillende versies van één framework te gebruiken

Stel dat het team dat aan de catalogus werkt, wil updaten naar de volgende versie van Vue. Helaas is het team dat met de betaling bezig is nog niet klaar. Ze moeten eerst een grote functie leveren en zouden over 3 maanden klaar zijn.
Wanneer de applicatie is opgedeeld in meerdere kleine applicaties, zijn ze volledig onafhankelijk. Ze kunnen de versie van een bibliotheek of een raamwerk verhogen zonder enig ander team te beïnvloeden.

En als een ander team een ​​nieuwe subtoepassing wil starten, kunnen ze de technologie gebruiken die ze willen zonder iedereen te beïnvloeden.§

👍 Voordelen:onafhankelijke implementaties

Dit is waarschijnlijk het grootste voordeel. "Teamcatalogus" kan onafhankelijk van "Teambetaling" werken en vrijgeven.

🤔 Nadelen:ontwerp systeemintegratie

Als je een Design System hebt geschreven in Vue, wil je het waarschijnlijk niet herschrijven in React alleen omdat een team iets wil experimenteren. In dit geval bent u wellicht geïnteresseerd in Web Components. Vanuit mijn ervaring is het geweldig. Maar als je wat doet, is het een ander verhaal. Bovendien wordt het niet ondersteund door IE11 (polyfills zijn nodig).

💡 Tip:u kunt webcomponenten genereren met vue-cli en dit commando:

vue-cli-service build --target wc --name foo 'src/components/*.vue'

🤔 Nadelen:teams op één lijn brengen is moeilijk

Als je nog steeds aan een eenvoudige oude monoliet werkt, zal het een heel lange reis zijn om daar te komen.
Als de backend zich nog niet in een microservice-architectuur bevindt, kun je ook niet in volledig geïsoleerde silo's werken. Misschien zal het Frontend-team onafhankelijk zijn, maar de achterkant niet.

🤔 Nadelen:optredens

Wanneer u uw app modulariseert, kan elke module worden opgesplitst in brokken (via tools zoals WebPack 4). U laadt de belangrijkste afhankelijkheden één keer en wanneer u de betalingspagina laadt, wordt de code geladen. Als u bestaande modules converteert naar een gescheiden/geïsoleerde toepassing, wordt het hoofdframework van elke toepassing op elke module geladen.

🤔 Nadelen:routering

Om van module A naar module B te gaan, moet module A het volledige pad kennen. Het is gebruikelijk om de URI hard te coderen. Immers:"Cool URI's veranderen niet" (W3C)

Tip #3:Wees aardig voor je winkel (Vuex)

Een van de grootste problemen met een op componenten gebaseerde applicatie is de winkel. Op het eerste gezicht ziet het er geweldig uit. De eerste keer dat ik de vue-tools zag, stond ik er helemaal versteld van. Ik begon het overal te gebruiken! Dan beginnen er problemen te komen.

  • 20 mutaties wanneer een pagina wordt geladen (maakt tijdreizen onmogelijk);
  • open een pagina, doe iets, ga naar een andere pagina en kom terug. De status wordt niet opnieuw geïnitialiseerd;
  • overdreven functies. Je moet voor alles een mutatie maken.

Hier zijn enkele tips om uw winkel onderhoudbaar te houden.

Gebruik de winkel niet te veel

Er zijn veel misvattingen over de winkel. Ik weet niet waarom, maar veel mensen denken dat:"Vue is om de gebruikersinterface te beheren en Vuex is om de applicatiestatus te beheren". Ik ben het hier sterk mee oneens. Op basis van mijn ervaring leidde het verplaatsen van alle logica in de winkel tot overhead en onnodige complexe functies. Ook meer code =meer oppervlakte voor bugs.

Meestal, als we existentiële vragen hebben zoals deze, wenden we ons tot de makers.

Ik heb ook nog een citaat van Dan Abramov geplaatst, vooral omdat Vuex gedeeltelijk is geïnspireerd door Redux. Ook hebben componentgeoriënteerde applicaties veel aandachtspunten.

Als ik mezelf afvraag:"moet ik de winkel gebruiken of niet?", doe ik meestal zoiets in mijn hoofd:

Met andere woorden, hier zijn enkele voorbeelden:

  • Opslaan "Huidige gebruiker, i18n-voorkeuren" → Ja.
  • "Gegevens geladen via API-aanroep" → Joker! Doe het minder onhandige. Ik bewaar het meestal in de staat van het onderdeel. Ik ben het ermee eens dat het soms zinvol is om deze gegevens met de rest van de app te delen.
  • Status gerelateerd aan een bewerkings-/aanmaakformulier → Nee.
  • 'Een UI-element wisselen' → Nee.
  • "Beheer een isLoading staat" → Nee.

Ik zeg niet dat je de winkel niet moet gebruiken. Gebruik het gewoon met spaarzaamheid!

Gebruik namespaced stores (voor modules)

const store = new Vuex.Store({
  modules: {
    catalog: {
      namespaced: true,
      state,
      getters: {
        getFeaturedProducts () { ... } // -> getters['catalog/getFeaturedProducts']
      },
    }
  }
})

Schrijf geen simplistische getters.

Om relevant te zijn, moet een getter enige logica bevatten. Als u toegang wilt tot een subproperty, geeft u de voorkeur aan mapState .

getters: {
  // 🤔 non useful getter
  getProducts: state => state.products,
  // 👍 useful getter
  getFeaturedProducts: state => state.products.filter(p => p.isFeatured),
}

Oorspronkelijk gepubliceerd op maxpou.fr.