Questions fréquentes sur SmooshGate

Pourquoi ce smoosh s'est-il passé ?

Une proposition de code JavaScript une fonctionnalité linguistique appelée Array.prototype.flatten s'avère Incompatible avec le Web. La livraison de la fonctionnalité dans Firefox Nightly a entraîné la création d'au moins un site Web populaire. de casser. Étant donné que le code problématique fait partie des outils très répandus MooTools bibliothèque, il est probable que beaucoup plus de sites Web soient concernés. (Bien que MooTools n'est pas souvent utilisé pour les nouveaux sites Web en 2018, il était autrefois très populaire et est encore présent sur de nombreux sites Web de production.)

L'auteur de la proposition a suggéré, en plaisantant, de renommer flatten en smoosh en pour éviter ce problème de compatibilité. La blague n'était pas claire pour tout le monde, les gens ont commencé à croire à tort que le nouveau nom avait déjà été décidé, et les choses ont rapidement évolué.

Que fait Array.prototype.flatten ?

Array.prototype.flat, initialement proposé sous le nom Array.prototype.flatten, aplatit les tableaux de manière récursive jusqu'à la valeur depth spécifiée, qui est la valeur par défaut à 1.

// Flatten one level:
const array = [1, [2, [3]]];
array.flat();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flat(Infinity);
// → [1, 2, 3]

La même proposition inclut Array.prototype.flatMap, qui équivaut à Array.prototype.map, sauf qu'il aplatit le résultat dans un nouveau tableau.

[2, 3, 4].flatMap((x) => [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]

Qu'est-ce que MooTools fait à l'origine de ce problème ?

MooTools définit sa propre version non standard de Array.prototype.flatten:

Array.prototype.flatten = /* non-standard implementation */;

L'implémentation de flatten dans MooTools diffère de la norme proposée. Cependant, ce n'est pas le problème. Lorsque les navigateurs sont livrés Array.prototype.flatten nativement, MooTools remplace la mise en œuvre. Cela garantit que le code s'appuyant sur le comportement de MooTools fonctionne comme prévu, que l'élément flatten natif soit disponible ou non. Aucun problème pour le moment !

Malheureusement, autre chose se produit alors. MooTools copie l'ensemble de méthodes de tableau personnalisées à Elements.prototype (où Elements est un API spécifique à MooTools):

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}

for-in effectue une itération sur les propriétés "énumérables", ce qui n'inclut pas comme Array.prototype.sort, mais elle inclut des propriétés attribuées régulièrement telles que Array.prototype.foo = whatever. Mais... Voici le surtitre : si vous écrasez une propriété non énumérable, comme Array.prototype.sort = whatever, il reste non énumérable.

Actuellement, Array.prototype.flatten = mooToolsFlattenImplementation crée une propriété flatten énumérable, qui sera copiée plus tard dans Elements ; Mais si les navigateurs livrent une version native de flatten, celle-ci devient non-énumérable ; et n'est pas copié dans Elements. Tout code s'appuyant sur MooTools Elements.prototype.flatten ne fonctionne plus.

Bien qu'il semble qu'il s'agisse d'un élément Array.prototype.flatten natif, enumerable réglerait le problème, il causerait probablement encore plus problèmes de compatibilité. Tous les sites Web qui utilisent for à in pour itérer un tableau (ce qui est une mauvaise pratique, mais qui arrive), génère alors soudainement une itération de boucle supplémentaire pour la propriété flatten.

Ici, le plus gros problème sous-jacent est la modification des objets intégrés. Extension les prototypes natifs est généralement reconnue comme une mauvaise pratique de nos jours, car elle ne se composait pas correctement avec d'autres bibliothèques et du code tiers. Ne pas modifier des objets qui ne vous appartiennent pas !

Pourquoi ne pas simplement conserver le nom existant et briser le Web ?

En 1996, avant que le CSS ne se généralise et bien avant que le "HTML5" ne devienne le site Web Space Jam a été mis en ligne. Aujourd'hui, le site Web fonctionne toujours comme il y a 22 ans.

Comment cela s'est-il produit ? Quelqu’un a-t-il géré ce site web pendant toutes ces années, chaque fois que les fournisseurs de navigateurs introduisaient une nouvelle fonctionnalité ?

Il s'avère que "ne pas casser le Web" est le principe de conception numéro un. pour HTML, CSS, JavaScript et toute autre norme largement utilisée sur Web. Si l'envoi d'une nouvelle fonctionnalité de navigateur entraîne l'arrêt des sites Web existants fonctionne, cela nuit à tout le monde:

  • les visiteurs des sites Web concernés subissent soudainement une mauvaise expérience utilisateur ;
  • les propriétaires du site Web sont passés d'un site Web parfaitement fonctionnel à non fonctionnelle sans qu’elle ne change quoi que ce soit ;
  • les fournisseurs de navigateurs qui proposent la nouvelle fonctionnalité perdent des parts de marché à cause des utilisateurs changer de navigateur après avoir remarqué "cela fonctionne dans le navigateur X" ;
  • Une fois le problème de compatibilité connu, les autres fournisseurs de navigateurs refusent La spécification de la caractéristique ne correspond pas à la réalité ("Il n'y a rien d'autre qu'une œuvre de fiction). ce qui n'est pas optimal pour le processus de standardisation.

Avec le recul, MooTools a fait le mal, mais a brisé le Web mais pas les utilisateurs. Ces utilisateurs ne savent pas ce que c'est de l'outil. Nous pouvons également trouver une autre solution et les utilisateurs peuvent continuer pour naviguer sur le Web. Votre choix est facile à faire.

Cela signifie-t-il que les API incorrectes ne peuvent jamais être supprimées de la plate-forme Web ?

Cela dépend. Dans de rares cas, des éléments géographiques incorrects peuvent être supprimés du Web. Même le fait de comprendre la suppression possible d'une fonctionnalité, ont besoin d'une télémétrie approfondie pour quantifier le nombre de pages Web dont le comportement a changé. Mais lorsqu'elle n'est pas suffisamment sécurisée, ou qu'elle est très rarement utilisée.

<applet>, <keygen> et showModalDialog() sont tous Exemples d'API incorrectes qui ont été supprimées de la plate-forme Web

Pourquoi ne pas se contenter de corriger MooTools ?

Appliquer un correctif à MooTools pour qu'il n'étende plus les objets intégrés est une bonne idée. Toutefois, cela ne résout pas le problème en question. Même si MooTools était pour publier une version corrigée, tous les sites Web qui l'utilisent doivent pour résoudre le problème de compatibilité.

Les utilisateurs ne peuvent-ils pas simplement mettre à jour leur copie de MooTools ?

Dans un monde parfait, MooTools publierait un correctif et chaque site web à l'aide de MooTools serait automatiquement mis à jour le lendemain. Problème résolu, n'est-ce pas ?

Malheureusement, cette approche est irréaliste. Même si quelqu'un identifie d'une manière ou d'une autre l'ensemble des sites Web concernés, trouvez les coordonnées de contacter tous les propriétaires de sites Web, et à tous les convaincre d'effectuer la mise à jour (ce qui peut impliquer une refactorisation l'ensemble de leur code base), l'ensemble du processus prendrait des années, au mieux.

Gardez à l'esprit que la plupart de ces sites Web sont anciens et n'ont probablement pas été entretenus. Même si le responsable est toujours là, il est possible qu'il ne soit pas un un développeur web hautement compétent comme vous. Nous ne pouvons pas nous attendre à ce que tout le monde aille et modifier son site web de 8 ans en raison d’un problème de compatibilité web.

Comment fonctionne le processus TC39 ?

TC39 est le comité chargé de faire évoluer le langage JavaScript via la norme ECMAScript.

Avec #SmooshGate, certains membres de l'équipe se sont amusés que "TC39 voulait renommer flatten en smoosh", mais c'était une blague qui n'était pas bien communiquée en externe. Les décisions importantes, comme renommer une proposition, ne sont pas prises à la légère. Elles ne sont pas prises à la légère. par une seule personne, et qui ne sont certainement pas prises du jour au lendemain sur la base Commentaire GitHub.

TC39 suit un processus de préproduction clair pour les propositions de fonctionnalités. les propositions ECMAScript et toute modification majeure qui leur est apportée (y compris la méthode changement de nom) sont discutés lors des réunions TC39 et doivent être approuvés par l'ensemble du comité avant qu'ils ne deviennent officiels. Dans le cas d'une Array.prototype.flatten, la proposition a déjà fait l'objet de plusieurs d'accord, jusqu'à l'étape 3, indiquant que la caractéristique prêts à être implémentés dans les navigateurs Web. Il est courant que des spécifications supplémentaires les problèmes qui surviendront lors de la mise en œuvre. Dans ce cas, le plus important des commentaires sont arrivés après avoir essayé de l'envoyer: la fonctionnalité, dans son état actuel, pour rompre le Web. Ce type de problèmes difficiles à prévoir explique pourquoi le processus TC39 ne se termine pas seulement une fois que les navigateurs proposent une fonctionnalité.

TC39 fonctionne sur consensus, ce qui signifie que le comité doit se mettre d'accord sur des modifications. Même si smoosh avait été une suggestion sérieuse, il semble probable que un membre du comité s'y opposerait en faveur d'un nom plus courant comme compact ou chain.

Le changement de nom de flatten en smoosh (même s'il ne s'agissait pas d'une blague) a n'ont jamais été évoquées lors d'une réunion TC39. Ainsi, la position officielle de TC39 ce sujet est actuellement inconnu. Aucune personne ne peut parler au nom de tous les membres de TC39 jusqu'à ce qu'un consensus soit trouvé lors de la prochaine réunion.

Les réunions TC39 sont généralement suivies par des personnes aux profils très variés certains ont des années d'expérience en conception de langages de programmation, d'autres fonctionnent sur un navigateur ou un moteur JavaScript, et un nombre croissant sont là pour représenter la communauté des développeurs JavaScript.

Comment l'équipe SmooshGate a-t-elle finalement été résolue ?

Lors de la réunion TC39 de mai 2018, #SmooshGate a été officiellement résolu en renommant flatten en flat.

Array.prototype.flat et Array.prototype.flatMap expédiés dans V8 v6.9 et Chrome 69.