Přístup k Micro-frontend Architecture (MVP) s NextJs

Jakmile se webové aplikace zvětší, je obtížné je spravovat. Podívejme se tedy na hlavní myšlenku inženýrství, která rozděluje problém na menší problémy. Takže rozšířením konceptů mikroslužeb na frontend můžeme rozbít obrovskou aplikaci na základě cest k miniaplikacím nebo MVP (Minimum Viable Product).

Kdy mám vybrat

Tuto architekturu musíme volit moudře, protože má také některé nedostatky. Pokud tedy pracujete na velké webové aplikaci a potřebujete rychlejší výstupy, které jsou na sobě nezávislé, kompromis by se vyplatil.

Proč zvolit Micro-frontends/MVP

Tento koncept rozpadu aplikací založených na trase může pomoci rychleji dodávat miniaplikace, čímž se eliminuje riziko poškození dříve nasazených MVP.
Myšlenkou mikrofrontendů je rozdělit webovou aplikaci na více funkcí jako nezávislé produkty, jejichž vlastnictví lze rozdělit mezi nezávislé týmy. Tato myšlenka umožňuje každému týmu fungovat v různých oblastech podnikání.

Nápad má spoustu technických kladů:

  • Princip jednotné odpovědnosti / obchodní centrum
  • Rychlejší a paralelní doprava produktů/funkcí
  • Technology Agnostic (jeden může běžet na Reactu, zatímco jiný si může vybrat Vue nebo Angular)
  • Odolná – Pokud jedna miniaplikace obsahuje pouze tuto miniaplikaci, je třeba ji vypnout nebo znovu nasadit.
  • Sdílení statických prostředků

Přístup Repo

Jelikož máme co do činění s multi-aplikacemi, musíme si vybrat mezi mono-repo nebo multi-repo přístupem. Není těžké uhodnout, že manipulace s jedním repo by byla mnohem jednodušší než manipulace s více repo operacemi. Takže v případě, že vaše mini-aplikace používají stejnou knihovnu/rámec, doporučuje se použít přístup Mono-repo. Tímto přístupem by stejné repo bylo zvyklé odesílat více sestavení na základě tras, které chcete spojit s MVP.
Pokud však chcete vyzkoušet více technik nebo chcete oddělit kód, budete nuceni použít multi-repo.
Jedním ze skvělých způsobů, jak spravovat vaše mono-repo, je toto

Principy návrhu architektury

Princip návrhu tedy říká, že každý mikrofrontend by měl:

  • Řiďte se zásadou jednotné odpovědnosti pravidel SOLID
  • Buďte zaměřeni na podnikání
  • Autonomní funkce
  • Frontend Framework Agnostic
  • Super odolný

Jak implementovat

Aniž byste zabírali více času, pojďme se hlouběji ponořit do toho, jak rozdělit aplikaci na mikro rozhraní.

Nejprve musíme naše mini aplikace kategorizovat. Za tímto účelem vytvořte soubor s názvem miniapp.js s následujícím obsahem:

const MINIAPPS = {
  minapp1: {
    id: 'app1',
    patterns: ['/minapp1'],
    subPath: '/mainSubpath/minapp1'
  },
  minapp2: {
    id: 'app2',
    patterns: ['/minapp2'],
    subPath: '/mainSubpath/minapp2'
  },
  minapp3: {
    id: 'app3',
    patterns: ['/minapp3'],
    subPath: '/mainSubpath/minapp3'
  },

};
module.exports = MINIAPPS;

Abychom vysvětlili výše uvedené, plánujeme rozdělit naši webovou aplikaci na 3 mikrofrontendy, z nichž každý má specifickou podcestu. Stručně řečeno, naším cílem je postavit 3 MVP, z nichž každý má samostatnou sestavu, s níže uvedenými cestami:

www.mywebapplication.com/mainsubPath/minapp1
www.mywebapplication.com/mainsubPath/minapp2
www.mywebapplication.com/mainsubPath/minapp3

Hlavní mainSubPath je přidán pro rozšiřitelnost více webových aplikací v rámci www.mywebapplication.com . V případě, že to není váš požadavek, můžete ponechat podcestu vlastnost být '/miniapp1'

Abychom tedy mohli číst trasy z next.config, vytvořte soubor, který má všechny trasy z aplikace nejlépe v kořenovém adresáři aplikace.
seznam tras

const APP_ROUTES = [
  {
    name: 'Feature 1',
    page: 'miniapp1/feature1',
    pattern: '/miniapp1/feature1'
  },
  {
    name: 'Feature 2',
    page: 'miniapp1/feature2',
    pattern: '/miniapp2/my-route/feature2'
  },
  {
    name: 'Feature 3',
    page: 'miniapp2/feature3',
    pattern: '/miniapp2/feature3'
  },
  {
    name: 'Feature 4',
    page: 'miniapp2/feature4',
    pattern: '/miniapp2/my-route/my-sub-route/feature4'
  },
  {
    name: 'Feature 5',
    page: 'miniapp3/feature5',
    pattern: '/miniapp3/feature5/my-feature'
  },
  {
    name: 'Feature 6',
    page: 'miniapp3/feature6',
    pattern: '/miniapp3/my-route/my-subroute/feature4'
  }
];
module.exports = APP_ROUTES;

Jen mějte na paměti, že při vytváření funkcí vytvořte složky s názvy feature1 se souborem index.js, spíše než s feature1.js ve složce stránek.


Nyní musíme do next.config.js napsat malou logiku, abychom mohli číst pouze konkrétní cesty potřebné pro každou miniaplikaci.
next.config.js
Na začátek souboru musíme přidat:

const MINIAPPS = require('./miniapp');
const APP_ROUTES = require('./routes-list');
const miniappToBeBuild = process.env.APP_NAME;
const basePath = __dirname;
const subDir = NODE_ENV === 'production' ? (miniappToBeBuild ? MINIAPPS[miniappToBeBuild].subPath : '/mainsubPath') : '';

if (miniappToBeBuild && MINIAPPS[miniappToBeBuild]) {
  console.log('MINIPP NAME ---> ', process.env.APP_NAME);
  console.log('MINIPP Subpath ---> ', MINIAPPS[process.env.APP_NAME].subPath);
}
const getExportPaths = () => APP_ROUTES.filter((appRoute) => {
  const filterFlag = MINIAPPS[miniappToBeBuild].patterns.filter((appPattern) => appRoute.pattern.indexOf(appPattern) === 0);
  return filterFlag.length > 0;
});
process.env.SUB_DIR = subDir;


a v module.exports sekce, musíme přidat níže uvedený kód.

module.exports = {
  assetPrefix: subDir,
  async exportPathMap() {
    const paths = {};
    let dynamicSection = '';
    let exportRoutes = APP_ROUTES;
    if (miniappToBeBuild && MINIAPPS[miniappToBeBuild]) {
      console.log(`Building miniapp-${miniappToBeBuild} with subpath-${MINIAPPS[miniappToBeBuild].subPath}`);
      exportRoutes = getExportPaths();
    }
    exportRoutes.forEach((routes) => {
      paths[routes.pattern] = { page: routes.pattern };
    });
    return paths;
  },

  generateBuildId: async () => version,
  webpack: (config, { isServer }) => {
    return config;
  }
};

V zásadě tedy funkci exportPathMap poskytuje next js zapouzdřit, pokud nechcete číst své trasy ze složky stránek a chcete mít vlastní logiku pro čtení tras. Takže v této funkci jsme přidali logiku, že ať projdeme jakoukoli APP_NAME, v sestavení se vytvoří pouze trasy začínající touto APP_NAME. (Jednou drobnou nevýhodou tohoto přístupu je, že se nevytvoří pouze požadované soubory js, ale to vůbec neškodí, protože žádný z nich není propojen ve skriptech požadovaných HTML)


Nakonec už jen potřebujeme napsat skripty, předat APP_NAME a vytvořit samostatné sestavení pro každou miniaplikaci.
Něco jako toto:-

package.json

"scripts": {
    "export:minapp1": "npm run clean && cross-env APP_NAME=minapp1 npm run build && cross-env APP_NAME=minapp1 next export && shx mv out/minapp1/* out/ && shx rm -r out/minapp1",
    "export:minapp2": "npm run clean && cross-env APP_NAME=minapp2 npm run build && cross-env APP_NAME=minapp2 next export && shx mv out/minapp2/* out/ && shx rm -r out/minapp2",
    "export:minapp3": "npm run clean && cross-env APP_NAME=minapp3 npm run build && cross-env APP_NAME=minapp3 next export && shx mv out/minapp3/* out/ && shx rm -r out/minapp3",
    "dev": "npm run build && next dev",
    "build": "NODE_ENV=production next build",
    "clean": "rimraf node_modules/.cache .next",
  }

Ke spuštění výše uvedených příkazů na systémech Mac i Windows 2 byly vyžadovány knihovny. Takže nezbytný předpoklad:npm i cross-env shx

Takže to je vše, přátelé, přidáním výše uvedených drobných úryvků je váš mikro frontend připraven. V případě, že chcete přidat další technologickou miniaplikaci, jednoduše vytvořte nové repo s touto technologií a v systému sestavení aktualizujte podcestu z '' na 'mainSubpath/miniapp4'.

V pozdějších příspěvcích ukážu, jak jsem vytvořil kanály CD/CD pomocí Azure devops.

Závěr

Micro frontends je lepší architektonický přístup, pokud máte obrovské repo, které je obtížné spravovat a jsou vyžadovány rychlejší dodávky, které by měly být na sobě nezávislé.

To je vše, lidi!!