---
# System prepended metadata

title: Xpecto Next.js Versionierbar
tags: [setup, xpecto]

---

###### tags: `xpecto` `setup`

# Xpecto Next.js Versionierbar

Idee: Ein NextJS Projekt als Core. Zudem ein weiteres Projekt welches den Core lädt und diesen erweitern könnte.

## Anforderungen

* Versionierbarer Core
* [`next.config.js`](https://nextjs.org/docs/api-reference/next.config.js/introduction) erweitern
* [Environment Variablen](https://nextjs.org/docs/basic-features/environment-variables) über `.env` / `.env.production` etc. auslesen
* Neue Pages einfügen
* [Optional] Pages aus dem Core erweitern
* Neue XForm-Komponenten einfügen.

## Mögliche Ansätze
* [Multi-Zones](https://nextjs.org/docs/advanced-features/multi-zones) & [Rewrites](https://nextjs.org/docs/api-reference/next.config.js/rewrites): 2 separat laufende Apps die über Multi-Zone Feature + Rewrites (Reverse-Proxy) zusammengeführt werden.
  * Core-App installiert über npm
  * Core-App kann über Extend-App gebaut & gestartet werden
  * Separate ENVs und Zonen
  * relativ harte Trennung von Core und Extend
* Transpilation & Import: Eine laufende Extend-App die Pages & Components aus der Core-App importiert und ggf. erweitert.
  * Core-App installiert über npm
  * Transpilation von Pages und Components über  [next-transpile-modules](https://github.com/martpie/next-transpile-modules) ([inoffiziell und etwas hacky](https://github.com/vercel/next.js/issues/706#issuecomment-795915128))
  * Erweiterung und Customisierung weitaus granularer als mit Multi-Zones
* Monorepo mit Pages und Components als NPM-Libs:
  * Pages und Components installiert über npm 

**Beispiel-Repo mit allen Ansätzen:** https://bitbucket.org/campudus/nextjs-whitelabel/src/master/


# Workshop 23.04.2021

![](https://i.imgur.com/xTgfVXG.png)

## Komponentenlibrary

* Semantic versioning
* Nachteil:
    * Anpassungen dauern etwas länger da erst die Library aktualisiert werden muss und dann über package registry (https://docs.gitlab.com/ee/user/packages/package_registry/index.html) in das Projekt reingezogen wird
* Schlank halten und nur absolute Basiskomponenten sollten hier rein
* Bedenken: Viele breaking changes da jede Änderung am Markup bereits ein breaking change sein kann
* Changelog automatisch Generierung
    * Codastic hat ein Open-Source skript dafür https://github.com/codastic/release
    * Auf Pull-Request Ebene oder auf commit-Ebene
    * Regeln wie commits/PRs benannt werden müssen!
* Best Practice:
    * Nutzt z.B. eine Komponente eine andere dann nicht hardcoded sondern als prop. Bsp: Cart nutzt Button. Dann Button als prop mitgeben. ([Inversion of Control](https://kentcdodds.com/blog/inversion-of-control))
* dart-sass https://sass-lang.com/dart-sass
    * Mit `use` kann man Variablen mitgeben um das Modul zu konfigurieren
        * Achtung, geht nur einmal beim ersten `use`!
        * z.B.
```
// theme-dark.scss
@use "sass:meta";

// Load tokens
@use "~@xpecto/tokens/tokens-dark" as tokens;

// Configure
@use 'config' with ( $envs: ( theme-dark ), $tokens: meta.module-variables("tokens") );

@use 'main';
```

* Custom Komponenten
    * Interface für jede Core Komponenten
    * Custom Komponenten die auf Core Komponenten sollten auf dem auf dem gleichen Interface wie die core Komponenten basieren

* Best Practices:
    * TypeScript macht Sinn (gerade bei der Komponentenlibrary)
    * Typescript > PropTypes (besonders bei Shared-Code)
    * Prefixe in der Komponentenlibrary nutzen (Namenskonflikte verhindern)
    * Designsystem Tokens besser mehr auftrennen als weniger
    * Designsystem granularer als initial notwendig
    * BEM > Utility-Framework
    * Besonderer Fokus auf Naming/Semantik (bspw. eher $space-40 als $space-large, da leichter erweiterbar)