Less.js: ES6 et cumul

Créé le 14 sept. 2015  ·  62Commentaires  ·  Source: less/less.js

J'aimerais (si jamais j'ai le temps)

  • [x] déplacer les bibliothèques vers es6/
  • [x] transpiler es6/ vers un dossier es5/
  • [x] utiliser le cumul pour créer un fichier unique de navigateur

Ce serait une nouvelle version majeure et je supprimerais également les promesses groupées du navigateur comme je l'ai mentionné dans d'autres problèmes.

Des objections avant que je le fasse ? Je ne vais pas commencer à tout convertir en es6 autre que les exigences (pour le cumul), mais d'autres personnes sont libres d'utiliser la "mise à niveau" de less.js comme moyen d'apprendre es6 si elles le souhaitent.


_Mise à jour par @matthew-dean -- J'ai fini par garder lib/ dans le même dossier pour conserver (une partie ?) de l'historique de git, au lieu de transpiler (transpiler ?) et de déplacer en même temps. Les modules ne se compilent pas en es5/ ou l'équivalent. Au lieu de cela, il existe une version à fichier unique CommonJS pour Node 6+, ainsi qu'une version de navigateur._

feature request high priority

Commentaire le plus utile

Conversion effectuée et fusionnée ! Voir : https://github.com/less/less-meta/issues/32

Tous les 62 commentaires

Non. Je réfléchis dans le même sens depuis un moment. Qu'en est-il de l'utilisation de TypeScript ? Cela pourrait faciliter le développement / les contributions d'avoir des indications de code / des liens d'objets réels. Bien que je ne sache pas si cela mettrait alors un fardeau / une barrière de connaissances.

Je pensais également dans le même sens que nous devrions envisager d'utiliser les collections es6 pour l'analyse / AST, puis d'utiliser un polyfill pour les versions es5 comme https://github.com/Benvie/harmony-collections. Dans les environnements es6 (ce que Node.js est maintenant, tout comme les derniers navigateurs), cela devrait théoriquement accélérer l'analyse / l'évaluation en raison de la réduction de la surcharge de mémoire et de la construction AST plus rapide.

Qu'en est-il de l'utilisation de TypeScript ? Cela pourrait faciliter le développement / les contributions d'avoir des indications de code / des liens d'objets réels. Bien que je ne sache pas si cela mettrait alors un fardeau / une barrière de connaissances.

Nous pouvons considérer qu'après ES6 - es6 n'exclut pas le tapuscrit puisque le tapuscrit est aussi un transpileur es6.. ce serait une étape supplémentaire après cela.

Personnellement, je ne recommanderais pas le tapuscrit à moins qu'il n'y ait un travail supplémentaire important ou une refactorisation en moins. Texte dactylographié de l'OMI

  • + facilite le développement pour les nouvelles personnes qui connaissent la dactylographie
  • + augmente la maintenabilité

    • exige que les gens connaissent ou apprennent une quantité minimale de tapuscrit


    • prend plus de temps à écrire du code pour qu'il soit typé

Je pensais également dans le même sens que nous devrions envisager d'utiliser les collections es6 pour l'analyse / AST, puis d'utiliser un polyfill pour les versions es5 comme https://github.com/Benvie/harmony-collections. Dans les environnements es6 (ce que Node.js est maintenant, tout comme les derniers navigateurs), cela devrait théoriquement accélérer l'analyse / l'évaluation en raison de la réduction de la surcharge de mémoire et de la construction AST plus rapide.

Je n'utiliserais pas ce polyfill, le projet semble mort (peut-être aussi parce que le nom harmonie est mort).

De plus, je ne serais malheureusement pas sûr que les équivalents natifs ES6 soient plus rapides - https://jsperf.com/property-access-object-array-map-weakmap/6. C'est triste de voir comment, par exemple, le polyfill Promise est plus rapide que l'implémentation native :(

:+1:

Tous les bons points. La normalisation sur ES6 / Babel rend souvent les choses non seulement plus faciles à écrire, mais aussi à lire, en particulier lors de l'héritage prototypique.

En ce qui concerne ce test jsperf, ce n'est pas vraiment un exemple juste. Je m'attendrais à ce que Weakmap soit plus lent pour ce test spécifique. En théorie, il serait peut-être préférable pour Less de créer un ensemble de formes et de types d'objets différents, puis de les évaluer. Pas sûr cependant. J'ai trouvé quelques bonnes bibliothèques que je veux éventuellement tester (et, espérons-le, ajouter) où nous pouvons nous connecter à des fonctions individuelles pour effectuer une analyse comparative granulaire, sans avoir à mettre de "crochets d'analyse comparative" dans la bibliothèque. J'espère mettre en place quelque chose (quand j'aurai le temps, qui sait quand ce sera) pour que vous puissiez faire une sorte de test jsperf sur les fonctions dans Less.js, mais avec des changements de développement / branche locaux vers Less vs. version actuelle et en utilisant quelques types de fichiers de test .less. Comme je l'ai déjà mentionné, nous ne devrions pas avoir besoin de deviner lequel est le plus rapide pour notre cas d'utilisation particulier. Nous pourrions théoriquement substituer une WeakMap à un certain niveau de fonction par rapport aux objets bruts, exécuter des benchmarks sur cet emplacement et décider en fonction du résultat.

@lukeapage a écrit :
Texte dactylographié de l'OMI

  • + facilite le développement pour les nouvelles personnes qui connaissent la dactylographie
  • + augmente la maintenabilité

    • exige que les gens connaissent ou apprennent une quantité minimale de tapuscrit


    • prend plus de temps à écrire du code pour qu'il soit typé

Et un avantage non mentionné et très important que vous ignorez :
Le mode typé de TypeScript vous oblige à utiliser des types de variables stables, ce qui applique des formes de type stables, ce qui améliore la capacité du compilateur à analyser à la fois statiquement _et_ dynamiquement votre code, ce qui produit un code _beaucoup mieux_ optimisé et arrête (ou du moins réduit considérablement) les backouts de code optimisé vers un code interprété lent.

Passer à TypeScript contribuerait probablement plus que de passer à ES6, à mon humble avis.

Par mode tapé, vous entendez l'interdiction Tout ?

J'ai essayé ça sur un petit projet et j'avais des annotations partout.. ça se termine
avec beaucoup de code car le transpiler n'est pas super intelligent.

quant au nombre de variables ayant des types de variables mutés, je ne suis pas sûr. alors..
pas convaincu que l'avantage de performance serait perceptible.

@rjgotten Je n'ai pas utilisé TypeScript mais ce sont de bons points. Si vous utilisez un environnement intellisense/autocomplete pour TypeScript, cela pourrait en fait aider les nouveaux contributeurs car il complèterait les types/formes d'objets au fur et à mesure que vous apportez des modifications. Correctement conçu, il pourrait servir comme une sorte d'outil d'auto-documentation/de familiarisation/de prévention des erreurs pour quelqu'un qui contribue aux changements de code. Mais la clé est probablement dans la conception TypeScript.

Dans l'ensemble, y aurait-il un avantage en termes de performances ? C'est plus difficile à déterminer. C'est plus l'artiste que la toile.

Même si je vise à utiliser TypeScript pour mes propres projets, je suis probablement un peu plus enclin à être d'accord avec @lukeapage , principalement parce que, à moins que l'un d'entre nous ici ne soit un expert en TypeScript, je ne suis pas sûr que nous pourrions utiliser efficacement de celui-ci initialement.

De plus, le passage à ES6 n'empêche pas d'utiliser TypeScript à l'avenir. L'objectif de Microsoft / Google est de faire de TypeScript 2.0 un sur-ensemble ES6, afin que nous puissions toujours commencer par ES6 / Babel, puis ajouter les types appropriés et passer au transpileur TypeScript. Je soupçonne que TypeScript va "gagner" les langages transpilés, simplement parce que les avantages en termes de temps de compilation / de saisie semi-automatique sont bien plus importants que JavaScript non typé. Donc... Je suppose que cela signifie que je pense que l'utilisation de TypeScript est probablement inévitable, mais cela ne signifie pas que nous devons l'utiliser tout de suite.

J'aimerais discuter d'une approche architecturale différente de Less à un moment donné, mais c'est plus une discussion tangente à cela.

Par mode tapé, vous entendez l'interdiction Tout ?

Non. J'utilise simplement des variables typées en général. Vous _pouvez_ interdire l'utilisation de Any en général, mais c'est (au moins pratiquement) une mauvaise idée car cela a tendance à entraîner beaucoup de gonflement du code pour simplement satisfaire le système de typage.

Cependant, l'utilisation de paramètres typés sur une fonction signifie que les appelants (au moins les appelants écrits en TypeScript) _doivent_ respecter le type donné. Cela signifie que les fonctions typées peuvent être utilisées pour protéger la stabilité du type sur le fonctionnement interne du compilateur Less, le cas échéant, et garantir que les fonctions particulièrement importantes seront bien optimisées. (N'oubliez pas ; les moteurs JS optimisent généralement au niveau de la fonction...)

Travail assez cool. Germaine à la discussion, je regardais le code et suis rapidement tombé sur :

if (typeof index === 'number') {   

AFAIK, ce type de contrôle d'intégrité ne serait jamais nécessaire dans TypeScript. Si le type d'index est converti au moment de l'exécution en chaîne à chaque fois pour faire une comparaison de chaîne afin de vérifier le type de valeur, des choses comme ça peuvent s'additionner. Dans TypeScript, s'il y avait un appel à une fonction qui passait un index, mais que ce type n'était parfois pas un nombre, et indexait seulement _accepté_ un nombre, alors la fonction échouerait au moment de la compilation à cause de types non concordants, plutôt que d'avoir besoin à tester au moment de l'exécution, lorsque ces vérifications sont plus coûteuses.

D'autre part, il se pourrait qu'il s'agisse d'un exemple isolé et rare ; c'est juste quelque chose que j'ai trouvé qui semblait pertinent.

Je pense que le plus grand avantage des types explicites est qu'ils permettent un outillage plus puissant. Trouver tous (et uniquement) les emplacements qui appellent une fonction ou la remplacent n'est qu'un raccourci clavier. Découvrir quelles fonctions les objets dont vous disposez ne représente aucun travail et la refactorisation est plus sûre car le compilateur génère plus d'erreurs. Cela facilite également l'apprentissage d'une nouvelle base de code - obtenir une vue d'ensemble, découvrir quelle partie du code dépend ou suivre le flux de code sans l'exécuter est plus difficile en javascript qu'en java (par exemple), car les éditeurs typés sont plus puissants.

Je n'ai pas encore utilisé TypeScript, donc je ne sais pas si les outils sont suffisamment matures pour que cela en vaille la peine. L'avantage du javascript est que tout le monde le connaît, TypeScript est moins connu.

Dans l'ensemble, je pense que le passage à TypeScript aurait du sens si nous prévoyions une sorte de refactorisation plus importante ou d'énormes nouvelles fonctionnalités, mais cela pourrait représenter trop de travail alors que nous ne faisons que corriger de petits bogues.

Je pense que le passage à TypeScript aurait du sens si nous prévoyions une sorte de refactorisation plus importante ou d'énormes nouvelles fonctionnalités, mais cela pourrait représenter trop de travail alors que nous ne faisons que corriger de petits bogues.

C'est peut-être le cas, et vraiment, pour être pragmatique, @lukeapage a déjà pris en charge le travail, donc je suis enclin à dire qu'il devrait prendre la décision finale à ce moment-là. :-)

Hé, à ce sujet : y a-t-il quelque chose que nous devrions faire pour informer les gens que la base de code change ? Je suppose que sinon vous aurez des conflits de fusion.

non, il ne devrait pas y avoir trop de conflits. la première étape est juste les modules es6 - pas
en déplaçant n'importe quel fichier, nous pouvons ajouter babel ou tapuscrit de manière transparente.

Salut, les gars, comment ça va maintenant ?

Je peux travailler là-dessus. @matthew-dean Accepteriez-vous une pull request ?

@alexlur Bien sûr ! Ma seule préoccupation est la refactorisation de la branche 3.x et l'absence de conflits de fusion. Il est donc préférable de bifurquer/brancher à partir de là. De plus, depuis que ce problème a été écrit, il existe maintenant une convention bien établie d'utilisation de src/ et dist/ . Cependant, lib/ est parfois utilisé comme src/ , il n'est donc probablement pas nécessaire de le renommer.

Il y aurait également un tout petit peu de réécriture du Gruntfile afin que les tests utilisent des builds et non lib/ . (Ce que fait le test du navigateur, c'est faire une construction dans test/ et non dist/ . Le dossier dist/ est une tâche Grunt spéciale pour les nouvelles versions. Lors des tests, il devrait construire pour test/ ) Après cela, tant que les tests réussissent, vous devriez être bon.

@matthew-dean Bonjour. J'ai terminé la refactorisation mais je ne sais pas comment configurer Gruntfile pour exécuter des tests sur les nouveaux fichiers construits.

Peut-être que ce que je peux faire, c'est fusionner vos modifications dans une branche distincte et voir comment intégrer des tests. Je regardais juste rapidement vos modifications. Corrigez-moi si je me trompe, mais at-rule est-il incorrectement le nœud assignment ? Ou Github a-t-il simplement gâché la façon dont il montrait cela?

Bonne prise, j'ai utilisé le mauvais fichier.

Existe-t-il une version minimale du navigateur / Node.js que less.js doit prendre en charge ? Node.js a une assez bonne prise en charge de Promise (depuis la version 0.12), tandis que dans le navigateur, l'utilisation est généralement réservée aux développeurs qui exécutent déjà les dernières versions de navigateur de toute façon.

Éditer:

Less.js prend en charge tous les navigateurs modernes (versions récentes de Chrome, Firefox, Safari, IE11+ et Edge)

Seul Internet Explorer 11 n'intègre pas Promise .

@alexlur
Pour la version dans le navigateur de Less, je suggérerais de créer une propriété less.Promise et de la définir sur window.Promise par défaut. Et puis demandez à Less de consommer la classe Promise via less.Promise .

De cette façon, les utilisateurs de navigateurs modernes ainsi que les utilisateurs qui ont poly-rempli globalement Promise avant le chargement de Less, verront tout fonctionner comme par magie. Et les utilisateurs qui ne veulent pas - ou pour une raison quelconque n'y sont pas autorisés - polyfill peuvent faire fonctionner les choses avec une petite étape supplémentaire. Il leur suffit d'attribuer manuellement l'implémentation Promise choisie à less.Promise avant d'utiliser Less.

@rjgotten @alexlur Less.js a déjà des polyfills Promise déjà configurés. Il n'est pas nécessaire d'y faire des travaux supplémentaires. La plupart du code utilise ce modèle :

https://github.com/less/less.js/blob/55380d49e96a6ed561cac4d13a774830aa3c17a3/lib/less/import-manager.js#L5

Côté Node, il y a ce problème toujours ouvert : https://github.com/less/less.js/issues/3121

Cependant, sans aucun retour, et avec un nombre assez modéré de contributeurs, je suis enclin à dire que Node 4+ est la voie à suivre pour le moment. Nous devrions mettre à jour les docs/tests pour refléter cela.

@matthew-dean Il devrait être prêt à être fusionné dans une branche distincte .

@alexlur Merci ! Je vais essayer de jeter un oeil bientôt. Sera probablement la semaine prochaine (à moins que quelqu'un d'autre ait le temps de vérifier).

Ce problème a été automatiquement marqué comme obsolète, car il n'a pas eu d'activité récente. Il sera fermé s'il n'y a plus d'activité. Merci pour vos contributions.

J'ai créé un fork refactorisé en TypeScript.

J'ai créé un fork refactorisé en TypeScript.

@glixlur 😮 wow, et tous les tests passent ? Et construit un less.js identique dans dist/ ?

@matthew-dean Je travaille toujours dessus, mais ma construction pour le navigateur n'a rencontré aucun problème jusqu'à présent en tant que pilote quotidien. Techniquement, l'utilisation du cumul donne à mon fork un avantage en termes de performances, mais je n'ai pas de données pour le sauvegarder.

@less/core Cela devrait être étudié pour voir si nous pouvons automatiser cela pour une conversion unique - https://github.com/lebab/lebab

@matthew-dean Je vous enverrai une pull request une fois que j'aurai terminé.

@glixlur Ah ! D'accord, dans votre PR précédent , vous avez dit que vous n'aviez pas le temps pour ça. Si vous travaillez encore dessus, 👍

@matthew-dean Je vais me limiter à la conversion en ES6 et laisser la partie TypeScript plus tard.

@glixlur Je pense que ES6 est probablement la première étape la plus "conviviale pour la communauté", donc c'est parfait. Je ne suis pas sûr que tout le monde soit d'accord avec TypeScript, mais un flux ES6 serait certainement formidable.

@matthew-dean Je suppose que les plates-formes les plus basses prises en charge sont Node 6 et IE11 ?

@glixlur Appveyor est actuellement configuré pour tester le nœud 4. Cela rendrait-il les choses plus difficiles ? Idéalement, ce serait un Babel-transforme un dossier src/ en (remplacé) lib/ (et dist/ pour le navigateur) dossier(s) pour distribution pour Node/navigateur. Je suppose donc que Babel fait la majeure partie du travail de transpilation vers ES5.

Fait , mais il faut que les tests fonctionnent. PhantomJS est obsolète et ne prend plus en charge quoi que ce soit après ES5.

@glixlur Sympa ! Re : PhantomJS, il faut vraiment le remplacer par quelque chose comme Chromy. Voir : https://github.com/less/less.js/issues/3240

@glixlur En outre, ceci est lié à Chromy / Chrome sans tête: https://github.com/less/less.js/issues/3262

@glixlur Concernant PhantomJS - ces tests s'exécutent sur la version du navigateur fournie, que vous transpilerez probablement dans ES5, n'est-ce pas? Pourquoi PhantomJS ne fonctionnerait-il pas avec le bundle de sortie ES5 ?

@matthew-dean Oui, mais il y a un bogue où Symbol est utilisé lors de l'exécution de PhantomJS avec un fichier transpilé par Babel.

@glixlur Vous avez besoin du babel-polyfill dans la sortie transpilée. C'est un bon indicateur qu'il ne transpile pas encore correctement. Voir des problèmes comme : https://github.com/babel/babel-preset-env/issues/203

@matthew-dean babel-polyfill ajoute 87,3 Ko minifiés au fichier de sortie. Vous ne voulez probablement pas cela.

@glixlur
Il y a d'autres raisons pour lesquelles vous ne voulez pas babel-polyfill . A savoir le fait qu'il affecte l'espace de noms global en publiant des polyfills sur window et en modifiant les prototypes de types natifs comme Array .

Regardez plutôt babel-runtime et le package babel-plugin-transform-runtime .

De plus, l'équipe iirc de Babel travaille à limiter les polyfills regroupés par transform-runtime dans le même sens que les babel-env limites prédéfinies des transformations de langage. Mais leur travail à ce sujet n'est pas encore terminé et généralement disponible. Cela finirait par un truc Babel 7, qui est toujours en version bêta de toute façon, donc pas directement utile. Mais certainement souhaitable pour l'avenir.

@glixlur @rjgotten Ah. J'aurais dû préciser que je ne sais pas exactement quelle solution utiliser re: Babel. Juste que c'est parce que Symbol n'est pas défini parce qu'il n'est pas polyfill (ponyfilled?), Ce qui serait également le cas dans IE11. Alors peut-être que ce n'est pas le polyfill, mais je pense qu'avec les bons paramètres Babel, cela devrait vous donner une définition étendue Symbol . Alors peut-être que c'est la version min du navigateur qui pose problème ?

avec les bons paramètres Babel, cela devrait vous donner une définition étendue Symbol

Ce sera en effet.
Ces paramètres reviennent à utiliser le plug-in transform-runtime et sa capacité à injecter des alias pour les nouveaux intégrés comme Symbol , au lieu de s'appuyer sur babel-polyfill .

Les phantomjs devraient-ils être obsolètes ?

Considérant qu'il est mort?
Probablement oui.

Conversion effectuée et fusionnée ! Voir : https://github.com/less/less-meta/issues/32

Eh bien, cette semaine, j'ai appris que Class en JavaScript n'est PAS simplement du sucre syntaxique pour les prototypes de fonctions, ce qui a causé ce problème : https://github.com/less/less.js/issues/3414

Ironiquement, j'ai rencontré la même chose avec un autre morceau de code sans rapport avec Less, il y a quelque chose comme 2 semaines et je me souviens distinctement de la pensée qui m'a frappé:

bon sang, je me demande si cette conversion ES6 pour Less causerait ce type de problème.

Eh bien: réponse à la question, je suppose?

Je n'envie _donc_ pas la tempête d'utilisateurs qui ont déversé leur mécontentement sur votre travail, @matthew-dean. Vous avez ma sympathie d'avoir à gérer cette situation. :le sourire:
Heureusement, il semble que personne ne soit devenu apocalyptique et cela a été géré de manière ordonnée.

@rjgotten lol Je veux dire, comment avez-vous pu anticiper quelque chose comme ça ? La chose la plus sûre aurait été de ne pas convertir du tout, ou de ne jamais utiliser de classes, mais cela rend la base de code moins détaillée (enfin, ou le sera potentiellement, il y a beaucoup de possibilités de nettoyage supplémentaire). Techniquement, l'intégration (historique) less-loader avec Less utilisait mal l'API (en utilisant une utilisation non documentée/non prise en charge de l'API), donc c'était une erreur de leur part, mais je sympathise avec les gens frustrés que une version ponctuelle non majeure provoquant un échec de build.

Par exemple, si quelqu'un pirate les prototypes de votre bibliothèque, comment codez-vous de manière défensive pour cela ? ?

🤷‍♂

@rjgotten

Techniquement, j'ai publié deux versions bêta après la conversion, MAIS... personne n'a moins de bêtas dans son pipeline. Il n'y a donc aucun moyen de tester 800 000 dépôts qui s'intègrent à Less et d'exécuter leurs tests. Avec les dépendances NPM, vous devez vraiment le publier et voir ce qui casse.

Une chose que nous pourrions faire à l'avenir est d'ajouter des personnes moins dépendantes plus importantes aux tests, si nous pouvons comprendre ce qu'elles sont ?

L'autre chose que j'aurais pu faire est de le publier en tant que version majeure, mais ... techniquement, il n'a AUCUNE modification avec rupture (intentionnelle), c'est-à-dire que les fonctionnalités prises en charge sont identiques et qu'il inclut quelques corrections de bogues, donc .. .. Je ne sais pas, c'était délicat.

Ouais. C'était délicat.

Je suppose que vous auriez pu essayer de simplement mettre quelque chose sur une balise .next ou quelque chose et faire en sorte que les gens testent leurs pipelines de construction avec. Mais les expériences passées indiquent que ce genre de chose est généralement ignoré.

Quoi qu'il en soit, version majeure ou non, vous finirez probablement par être obligé de simplement "essayer" et de voir ce qui casse.

Ne vous méprenez pas cependant : le refactor est une très bonne chose. À l'avenir, cela devrait généralement prendre une bonne part du fardeau de la maintenance.


Par exemple, si quelqu'un pirate les prototypes de votre bibliothèque, comment codez-vous de manière défensive pour cela ? ?

Vous ne le faites littéralement pas.

C'est comme si les gens se plaignaient que leur IL émis par le runtime soigneusement orchestré pour accéder aux membres privés en C # se rompt dans les versions mineures. Si vous vous mêlez des internes, vous devez savoir dans quoi vous achetez. :le sourire:

@rjgotten En parlant de refactoring...

..... Une des choses que j'ai découvertes au fil du temps dans la base de code Less est qu'il existe un certain nombre d'endroits où il y a des mutations légères/subtiles sur les objets dans l'AST. Une nouvelle propriété ici / une méthode ajoutée sur une instance là-bas, et j'admets pleinement l'avoir fait parfois avec des fonctionnalités que j'ai fusionnées, car en JavaScript, vous pouvez muter ce que vous voulez, quand vous le souhaitez, que vous documenté/défini cette propriété ou non.

Il y a eu une discussion sur la question de savoir si TypeScript ou simplement JS moderne serait la réponse. J'ai réalisé que le fait de ne pas avoir de types ou d'interfaces d'objets claires rend parfois très difficile la base de code Less d'une manière qu'aucune documentation ne pourrait résoudre ou même JSDocs pourrait résoudre.

J'ai configuré le nouveau pipeline pour autoriser le lissage TypeScript _si_ vous avez les types appropriés dans JSDoc, mais l'utilisation de JSDoc pour la saisie est waaaaaaaay plus verbeuse / visuellement bruyante que TypeScript, et il existe certaines fonctionnalités de saisie que TS ne prend tout simplement pas en charge via les annotations JSDoc seules . Il n'y a pas de combinaison d'outils JSDoc / ESLint qui puisse résoudre certaines de ces choses que TS vous offre gratuitement.

Donc, je suppose que tout ce que je dis, c'est qu'après avoir utilisé TypeScript de manière significative au cours de la dernière année et avoir passé des années dans la base de code Less, je dirais que 95% de la courbe de confusion/frustration/apprentissage de comprendre comment Less fonctionne ont été évités si les objets avaient des types de compilation appliqués. J'ai souvent passé beaucoup de temps dans un débogueur à définir des points d'arrêt et à déterminer quelles sont _réellement_ les propriétés d'un objet, au lieu de la façon dont il est défini dans un fichier.

Par exemple, il existe un certain nombre de fonctionnalités de Less qui, lors de l'évaluation, reposent sur la propriété Ruleset d'un nœud paths . À partir de ce constructeur , pouvez-vous me dire quelle est la propriété paths et quelle forme aura-t-elle ? (Indice : vous ne pouvez pas, car ce n'est pas là.)

Dans TypeScript (avec les paramètres tsconfig courants), cela ne serait pas autorisé. Il ne compilerait même pas. Vous seriez obligé de spécifier la forme de paths , et exactement ce qu'il y aurait dedans, ce qui donnerait à son tour une documentation claire et spécifique (et des conseils de code) à quelqu'un explorant la base de code.

Donc, je suppose qu'à ce stade, je suis passé de la pensée "TypeScript est quelque chose à considérer" à l'impression "Si votre projet public n'est pas en TypeScript, vous avez une dette technique importante". Je ne commencerais jamais un référentiel open source sans lui, car il aide intrinsèquement à résoudre la consommation et la maintenabilité. Vous avez toujours besoin d'une documentation claire, mais au moins elle applique un codage extrêmement clair et cohérent.

C'est juste que je réfléchis à la direction à prendre à partir d'ici et aux moyens de prévenir les points douloureux à l'avenir.

_( Addendum : au cas où ce ne serait pas clair, je ne critique pas à 100 % le travail historique de qui que ce soit dans la base de code Less. Je me dis "Oof, j'aurais aimé ne pas avoir fait ça", ou j'aurais aimé le faire différemment. Et j'ai certainement ajouté des choses dont je me rends compte maintenant qu'elles auraient pu avoir un impact négatif sur la maintenabilité. Tout le monde a fait de son mieux.)_

@matthew-doyen
J'ai configuré le nouveau pipeline pour autoriser le peluchage TypeScript si vous avez les types appropriés dans JSDoc, mais l'utilisation de JSDoc pour la saisie est waaaaaaaay plus verbeuse / visuellement bruyante que TypeScript, et il existe certaines fonctionnalités de saisie que TS ne prend tout simplement pas en charge via les annotations JSDoc seules . Il n'y a pas de combinaison d'outils JSDoc / ESLint qui puisse résoudre certaines de ces choses que TS vous offre gratuitement.

Réellement; J'ai rencontré le problème avec le support JSDoc étant moi-même moyen pour l'inférence de type.
Heureusement, vous pouvez utiliser les fichiers de déclaration .d.ts à côté des fichiers source .js , sans avoir besoin d'utiliser entièrement TypeScript et d'avoir besoin du compilateur.

Auparavant, il était beaucoup plus difficile de travailler avec des fichiers de déclaration, mais les versions modernes du compilateur de TypeScript associent automatiquement un fichier .d.ts côte à côte avec un fichier .js tant que les deux sont nommés le même.

C'est peut-être ce que vous cherchez.

@rjgotten Pouvez-vous expliquer un peu plus (ou un lien si vous connaissez une bonne ressource), comment cela pourrait bien fonctionner avec la base de code de Less ? Comme dans, comment faites-vous cela sur un fichier par niveau de fichier ? Existe-t-il un fichier $# .d.ts .js ? Ou les regroupez-vous ?

Quels sont les avantages d'avoir un fichier .d.ts par rapport à l'utilisation de TypeScript dans la source ? Pourquoi passer du temps à créer des fichiers .d.ts au lieu de simplement définir ces types dans les fichiers ?

@rjgotten Je parlais au développeur de Chevrotain aujourd'hui, et il dit que ce qu'il fait est de développer dans TS _MAIS_ il gère en fait un fichier api.d.ts comme une préoccupation distincte. De cette façon, tout changement de type sur les fichiers source (tels que les nœuds d'arbre) ne modifie pas de manière transparente/invisible l'API publique sans un changement explicite du fichier de types d'api.

Ensuite, il utilise un test avec une assertion que les types internes et les types d'API publics correspondent -> https://github.com/SAP/chevrotain/blob/master/packages/chevrotain/test_integration/definitions/api_type_checking.ts#L1 - L2

La méthode de Chevrotain est un bon moyen de faire en sorte que votre API publique ne change pas accidentellement. Très robuste, si vous pensez avoir besoin de ce niveau de protection. Mais entraîne également des frais généraux.


Concernant l'utilisation des fichiers de déclaration .d.ts pour contenir les typages .js :
C'est en fait les deux.

S'ils vont côte à côte, alors tout IDE soutenu par le compilateur TypeScript pour les suggestions automatiques, les peluches, etc. détectera automatiquement les frappes. Afaik _aussi_ si ces scripts avec des typages côte à côte sont importés de node_modules , ce qui est plutôt sympa.

Vous pouvez également mettre des typages dans un seul (ensemble de) fichier(s) .d.ts comme api.d.ts , puis utiliser JSDoc pour importer explicitement les types déclarés. La prise en charge de JSDoc dans TypeScript a une saveur spéciale de @typedef pour cela avec la syntaxe d'importation. Par exemple

/**
 * <strong i="17">@typedef</strong> {import("../api.d.ts").MyType } MyType
 */

L'utilisation d'un seul fichier de typage groupé est une bonne idée si vous devez faire passer votre paquet par une étape de transpilation avant la distribution. Dans un tel cas, ce que les utilisateurs verront réellement require() ou import {} ne seront plus les fichiers source d'origine. C'est-à-dire qu'ils ne bénéficieraient pas de frappes côte à côte.

Cette page vous a été utile?
0 / 5 - 0 notes