7.7 KiB
7.7 KiB
options, theme
| options | theme | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
Définition des environnements de développement du package
- on défini un seul environnement (default)
- la fonction forEachSupportedSystem à pour
fonction de générer un élément pour chaque architecture supportée par le package
- ces architectures sont définie à la ligne 8 et correspondent aux architectures supportée par nix.
- Dans cet environnement, on fournis les packages suivants
- nodejs c'est un projet vue.js, donc faut bien un runtime
- yarn ici on préfèrera yarn pour pouvoir utiliser yarn2nix afin de générer les dépendances.
- webstorm
- je l'installe que pour ce projet, donc ça me permet de le garbage collecter quand j'en ai pas besoin (merci nix)
- yarn2nix
- yarn2nix est un outil qui vas lire notre fichier package.json et générer un fichier yarn.nix avec toutes nos dépendances packager pour nix, pour des question de reproductibilité, lors du build avec nix, les outils n'ont pas accès à internet, il n'est donc pas possible de juste faire un "yarn add".
path: shoblog_code.nix
language: nix
Définition des packages
- d'une manière similaire aux devShells, on vas ici générer un package par architecture supportée. Lors du build (qui se fait généralement localement), nix va néanmoins builder uniquement le package correspondant à l'architecture de la machine.
- Pour ce faire, on utilise la fonction
mkYarnPackage qui fournit diverses options pour générer un package
manager par Yarn
- name: assez explicite, le nom du package générer
- src: les source sur lequel la fonction va se baser pour générer le package
- PackageJSON: package.json
- yarnLock: yarn.lock
- yarnNix: Ah ! C'est ici qu'on
retrouve notre fameux yarn.nix.
- En fait, lors du process de build et pour pour des raisons de reproductibilité, les programmes n'ont pas accès à internet. Chez nix, toutes les dépendances doivent être connue et regroupée à l'avance. Pour ce faire, yarn2nix nous génère un fichier yarn.nix définissant sous forme de package nix toutes les dépendances de notre projet, ainsi lors du build, nix vas toutes les pull, donner le résultat à mkYarnPackage qui vas les installer dans son environnement de build.
- Et pour finis, les phases de notre build. Par défaut, mkYarnPackage va juste chercher à build un binaire basée sur la configuration de notre package.json, dans notre cas
path: shoblog_code.nix
language: nix
buildPhase
Le build d'un package sous nix est découpé en plusieurs phases, si la plupart sont généralement transparente, celons le cas, certaines ont besoin d'être override en fonction des besoins. Ici, l'on cherche à packager des assets statiques, donc:
- première étape, appeler
runhook preBuild, rien à voir avec notre affaire, mais cela permet à d'éventuel futur dev de venir surcharger notre package sans toucher à notre buildphase, chaque phase à des pré et post hook de la même manière. mkdir $TEMPDIR/dist, on créer un dossier temporaire pour nos fichiers de buildyarn run build --outDir $TEMPDIR/dist, on run notre script de build en précisant notre dossier temporaire comme output- et on run le hook de postBuild
path: shoblog_code.nix
language: nix
installPhase
Cette phase a pour rôle de placer les fichiers résultant du build dans le store de nix, je passe sur les hook qu'on à déjà vu précédemment
mkdir -p $out/, $out est une variable spécifique à cette phase de build qui pointe vers le dossier final attribué par nix pour notre package.cp -r $TEMPDIR/dist/ $out/, on copie les fichiers de notre build dans le dossier ainsi créer et zou ! :3
path: shoblog_code.nix
language: nix
Résultat
Hop, un petit coup de nix build et sous vos yeux ébahis, nix nous pull toutes
nos dépendances, build notre projet et le place au chaud dans son store.
Bon c'est vachement bien tout ça, mais pourquoi faire ?
On verra les avantages en détails dans d'autres articles (peut-être même dès demain ?
mystère mystère...) mais voici déjà quelques bullet points
- Reproductibilité
- Nix nous assure que, pour des entrées données, le résultat sera toujours le même, ainsi, il nous est possible de pin un commit spécifique de nixpkgs pour figer la release de notre paquet dans le temps. Contrairement à un package manager plus classique (apt par exemple), lors du build de votre paquet, vous serez ainsi assurer de toujours pull la même version de node tant que l'on update pas le flake.lock du projet.
- Isolation
- Nix installe chaque dépendance dans un dossier appellé le store, chaque dépendance étant installer dans un dossier au hash unique basé sur le nom du package et sa version. Ce qui fait qu'il est parfaitement possible d'avoir deux projets utilisant deux versions de node différentes sans aucun problème, et ce sans avoir besoin de docker, d'environnement virtuel ou de faire mumuse avec des liens symboliques. Bonus, si un autre projet nécessite la même version de node, nix va simplement utiliser celle déjà installer, ce qui évite les duplicatas.
- Tracking
- étant donné que toutes les dépendances de chaque package sont déclarées dans
le
flake.nix, il suffit de lire ce dernier pour savoir quels paquets sont nécessaires à son déploiement. De plus, si l'on enlève un paquet de l'environnement, nix vas pouvoir checker si ses dépendances sont utiliser par d'autres paquets, et dans la négative, les supprimer pour économiser la place.
- étant donné que toutes les dépendances de chaque package sont déclarées dans
le
- Configuration
- Un peu hors du scope de cet exemple, mais il est possible de définir une fonction d'override pour un paquet afin de permettre à l'utilisateur final de ce dernier de spécifier des paramètres à ce dernier au moment du build. Que ce sois l'utilisation d'une version spécifique de node, ou une clé d'API par exemple.
- en utilisant NixOS, il est possible de définir des modules que l'utilisateur peut importer dans la configuration de son système afin de déclarer des services, installer et configurer d'autres packages, configurer des interfaces réseaux, ect... Cela peut permettre d'automatiser grandement le déploiement de certains projets et de grandement organiser ses configurations (comme avec la déclaration de virtualhost nginx par exemple, teasing teasing...)