Le CSS minifié doit-il être stocké dans Git?

10

J'utilise Gulp pour générer du CSS minifié à partir de mon code SASS pour un projet sur lequel je travaille.

Je me demandais s'il était considéré comme la meilleure pratique pour régénérer ce CSS minifié lors de la diffusion en direct de Git ...

ou

Pour stocker les fichiers CSS minifiés dans Git afin qu'ils soient automatiquement poussés en direct vers la production sans autre travail de la part du serveur?

J'apprécierais les idées des gens à ce sujet. Merci!

Connor Gurney
la source
Il n'y a qu'un seul endroit css / js / etc. doivent être conservés: /dev/null.
R .. GitHub STOP HELPING ICE
(C'est parce que votre serveur Web est parfaitement capable d'utiliser le transport gzippé.)
R .. GitHub STOP STOPINGING ICE
Le stockage de CSS compressés et non compressés signifie que vous avez maintenant deux versions de la même chose. Quelle est la version canonique? Il est facile d'envisager le scénario où un développeur met à jour le CSS compressé et un autre met à jour le CSS non compressé. Vos deux atouts ont maintenant divergé. Bien sûr, le processus devrait empêcher cela, mais c'est une perspective réaliste avec par exemple un nouveau développeur dans l'équipe.
Qwerky

Réponses:

13

"Ça dépend." Pour un suivi de développement normal, non. Pour les déploiements cloud et DevOps, cependant, c'est souvent pratique, voire nécessaire.

La plupart du temps, @ptyx est correct . En effet, son «non» pourrait être exprimé un peu plus catégoriquement. Quelque chose comme "Non. Non! OMG NON! "

Pourquoi ne pas stocker des ressources minifiées ou compressées dans un système de contrôle de source comme Git?

  1. Ils peuvent être régénérés presque trivialement par votre processus de construction à la volée à partir du code source. Le stockage des ressources compressées consiste essentiellement à stocker deux fois le même contenu logique. Il viole le principe "ne vous répétez pas" (alias DRY ).

  2. Une raison moins philosophique mais plus pratique est que les actifs minifiés / optimisés ont une très faible compressibilité lorsqu'ils sont stockés dans Git. Les systèmes de contrôle des sources fonctionnent en reconnaissant les changements ("deltas") entre les différentes versions de chaque fichier stocké. Pour ce faire, ils "diffèrent" le dernier fichier avec la version précédente et utilisent ces deltas pour éviter de stocker une copie complète de chaque version du fichier. Mais les transformations effectuées à l'étape de réduction / optimisation suppriment souvent les similitudes et les points de cheminement utilisés par les algorithmes diff / delta . L'exemple le plus trivial est la suppression des sauts de ligne et autres espaces; l'actif résultant n'est souvent qu'une seule longue file. De nombreuses parties du processus de création Web - des outils tels que Babel , UglifyJS , Browserify ,Moins et Sass / SCSS - transforment les actifs de manière agressive. Leur sortie est perturbable; de petits changements d'entrée peuvent entraîner des changements majeurs de sortie. Par conséquent, l'algorithme diff croit souvent qu'il voit à chaque fois un fichier presque entièrement différent. Vos référentiels se développeront ainsi plus rapidement. Vos disques peuvent être suffisamment volumineux et vos réseaux assez rapides, ce qui n'est pas un problème majeur, surtout s'il y avait une valeur à stocker deux fois les actifs minifiés / optimisés - bien que sur la base du point 1, les copies supplémentaires puissent être inutiles à 100% gonfler.

Il existe cependant une exception majeure à cela: les déploiements DevOps / cloud. Un certain nombre de fournisseurs de cloud et d'équipes DevOps utilisent Git et similaire non seulement pour suivre les mises à jour de développement, mais également pour déployer activement leurs applications et leurs actifs sur des serveurs de test et de production. Dans ce rôle, la capacité de Git à déterminer efficacement "quels fichiers ont changé?" est aussi important que sa capacité plus granulaire à déterminer "ce qui a changé dans chaque fichier?" Si Git doit faire une copie de fichier presque complète pour les actifs minifiés / optimisés, cela prend un peu plus de temps que cela ne le serait autrement, mais ce n'est pas grave car il fait toujours un excellent travail en évitant une copie de "chaque fichier du projet" sur chaque déployer le cycle.

Si vous utilisez Git comme moteur de déploiement, le stockage d'actifs minifiés / optimisés dans Git peut passer de "non!" à souhaitable. En effet, cela peut être nécessaire, par exemple si vous manquez de solides opportunités de build / post-traitement sur les serveurs / services sur lesquels vous déployez. (Dans ce cas, la segmentation des actifs de développement et de déploiement est une boîte de vers distincte. Pour l'instant, il suffit de savoir qu'elle peut être gérée de plusieurs manières, y compris avec un seul référentiel unifié, plusieurs branches, sous-dépôts ou même plusieurs référentiels qui se chevauchent. )

Jonathan Eunice
la source
1
Merci pour ça! Très appréciée. J'ai plutôt marqué cela comme la réponse car cela semble beaucoup mieux expliqué.
Connor Gurney
1
git ne stocke pas que les deltas. SVN le fait, mais git utilise un mécanisme beaucoup plus complexe pour stocker les fichiers. Certaines personnes vous disent qu'il stocke une copie complète de chaque fichier, mais d'après ce que je comprends, c'est également incorrect. Je n'essaierai pas d'entrer dans le détail, car je ne suis pas tout à fait clair à ce sujet.
jpmc26
Je pense que vous pouvez obtenir la nuance en changeant simplement "et ne stocker que les nouveaux deltas" vers quelque chose dans le sens de "et utiliser ces deltas pour éviter de stocker une copie complète de chaque version du fichier". Cela ferait valoir votre argument, serait exact dans les faits et éviterait de se pencher sur la question de savoir comment cela est fait pour un système de contrôle de source donné.
jpmc26
DevOps pourrait-il simplement utiliser des hooks git pour déclencher automatiquement la minification sur le serveur déployé, en tirant le meilleur parti des deux mondes?
Buttle Butkus
@ButtleButkus Dépend du serveur déployé. Pour dépendre des crochets de poste, vous devez 1 / supposer que les transpilers, les minificateurs et les optimiseurs appropriés sont présents sur la cible, ou 2 / les charger avant d'exécuter les crochets de poste. 1 / est risqué. 2 / impose un coût / latence de charge à chaque déploiement. Il introduit également de nouveaux modes de défaillance possibles et une obligation de déboguer les crochets de publication dans un environnement distant, opaque et transitoire. Pas idéal. Les crochets ne sont donc pas une solution miracle. La pré-conversion / optimisation des actifs peut être inélégante, mais elle est robuste et pragmatique.
Jonathan Eunice
17

Non.

Le contrôle de source ne doit contenir que la source. S'il est généré à partir de la source, il n'y appartient pas - et doit être généré par votre processus de génération.

La raison fondamentale pour laquelle vous ne voulez pas contrôler à la source les artefacts de construction intermédiaires est que si vous le faites, il devient vraiment difficile de savoir si ce que vous exécutez provient de la source que vous venez de modifier ou d'un produit intermédiaire que vous n'avez pas réussi à reconstruire. .

ptyx
la source
3
Pensez au code généré comme vous le pensez au code exécutable.
candied_orange
3
Ce principe n'est pas toujours vrai. Si vous avez des fichiers générés avec des outils lourds que vous ne pouvez pas attendre d'un utilisateur, il peut être judicieux de mettre les fichiers générés dans git. Beaucoup de gens ont même mis des configurescripts autoconf générés dans git pour cette raison.
R .. GitHub STOP HELPING ICE
@R ..: Idéalement, vous maintenez un référentiel d'artefacts séparé pour ces choses, mais la réalité est rarement idéale.
Kevin
@R vous pouvez faire des compromis - mais c'est juste cela. Et dans le cas de la minification CSS, je ne pense pas que les outils soient qualifiés de "lourds" ou "lents" ou "peu pratiques". De plus, il existe d'autres mécanismes d'injection de dépendances (maven, ivy ...) qui fonctionnent bien et ne nécessitent pas que vous mettiez du code généré dans votre contrôle de code source.
ptyx
1
@ButtleButkus Je n'ai pas beaucoup d'expertise sur le cas des devops. Ce que j'ai vu, c'est git utilisé comme un mécanisme de transport / libération / déploiement (très pratique et flexible), plutôt que simplement comme contrôle de source. À moins que le git 'source' et le git 'delivery' soient séparés (dépôts séparés ou branches séparées), cela signifie que vous devez compromettre quelque peu la chaîne source-> build-> livrable - par exemple, vous vous retrouverez avec une production ayant du code source et des branches supplémentaires qui traînent, et le développement avec des produits binaires inutilisés. C'est un compromis pragmatique, mais je préfère séparer les préoccupations lorsque je le peux.
ptyx