France-ioi / codecast

Codecast C learning platform (formerly fioi-recorder).
MIT License
30 stars 17 forks source link

[Fix] Don't compress chunks in terser because it breaks the compiled code of some Node modules #480

Closed SebastienTainon closed 4 months ago

SebastienTainon commented 4 months ago

Contexte :

Dans la lib de proxy proxy-compare, il y a cette fonction :

export const trackMemo = (obj: unknown) => {
  if (isObjectToTrack(obj)) {
    return Symbol() in obj;
  }
  return false;
};

En environnement de production, elle est compilée (en gros) en :

 export const trackMemo = (obj: unknown) => {
  return !!isObjectToTrack(obj);
};

La différence, c'est qu'il n'y a pas le ... in ... qui est effectué. Et c'est ce tout petit truc qui fait que y'a un comportement différent en prod. Car en fait ce "in" va logger un appel au handler has du proxy JavaScript d'un objet memoisé, et donc la lib de memoisation va détecter une utilisation de l'objet, et donc va mettre à jour son cache de la version de l'objet qu'elle avait, et donc récupérer une nouvelle version - la bonne - de l'objet, en l'occurence le tableau des test de la tâche. Alors qu'en production, il n'y a pas cet appel au in, donc pas d'appel au handler du proxy, donc la lib de memoisation ne logge pas d'utilisation de l'objet donc pas de mise à jour du cache donc utilisation d'une version erronée de l'objet donc mauvaise liste de tests.

Le compilateur convertit automatiquement Symbol() in obj en true.

En désactivant précisément l'option compress.unused de Terser, ce problème de compilation est résolu.