Actualizando Lodash de 3.x a 4.x

Hay varios cambios que rompen código de la versión anterior al pasar de Lodash 3.x a 4.x; todos los cambios están detallados en el registro histórico de cambios de Lodash. Además, hay una lista de funciones obsoletas (deprecated), con una expresión regular para encontrar usos de las mismas en tu código.

Sin embargo, dado que ambos recursos no son exhaustivos, listaré los cambios que encontré al realizar mi propia migración, a fin de ayudar a quien atraviese el mismo proceso.

Cambios de nombre directos

Esta sección incluye funciones donde sólo el nombre cambió, vale decir, los argumentos y retorno son los mismos que en 3.x.

3.x 4.x
contains includes
first head
rest tail
invoke invokeMap
padLeft padStart
padRight padEnd

Cambios de nombre directos (en caso de no usar thisArg)

Esta sección incluye funciones en donde el único cambio es quitar el argumento "thisArg". Si el mismo no se usa, se puede renombrar y listo. Si se usa thisArg en 3.x, se puede eliminar si sólo se usa para acceder a los elementos de la colección, ya que eso se puede hacer con una función "iteratee" en el segundo argumento. Si se estaba usando para vincular a otro objeto, se puede usar el bind estándar.

3.x 4.x
any some
indexBy keyBy
all every

Argumentos diferentes

3.x 4.x Cambios
extend assignIn Si se estaba usando el argumento "customizer", usar _.map antes de assignIn para realizar esa conversión. Si se estaba usando thisArg, eliminarlo o usar bind
pluck map El "plucking" se puede hacer con _.map, pasando un string con el nombre de la propiedad como segundo argumento (atajo de propiedad), o un array de strings para seleccionar más de una propiedad.
sum sumBy Si sólo se usa para sumar números en un array, se puede dejar sum intacto. Sin embargo, si se están sumando valores de propiedades en un array de objetos, hay que usar sumBy (se puede usar el atajo de propiedad en lugar de una función; ver ejemplos en la documentación de Lodash).
omit omit Cambiar el segundo argumento por un array de string en lugar de un string, si se usa el atajo de propiedad (como con pluck).
uniq uniqBy Mismo cambio que sum y sumBy (el atajo de propiedad es válido, probarlo en el REPL de la documentación de Lodash).
pick pick En 4.x, el 2do argumento no puede ser una función predicado, sólo un array de strings con nombres de propiedades a seleccionar.
min minBy Mismo cambio que sum y sumBy.
max maxBy Mismo cambio que sum y sumBy.

Special case: _.zipObject

Esta función es complicada, porque a primera vista no cambió; sin embargo, la forma de interpretar los argumentos cambió. En 3.x, el primer argumento puede ser un array donde cada elemento es un array de 2 elementos representado un par clave-valor. Sin embargo, en 4.x, el primer argumento es un array con claves, y el segundo un array con los valores. Ergo, si ves _.zipObject recibiendo un solo argumento, eso va a fallar en 4.x. Dado que transformar los argumentos a la nueva convención en cada llamada es molesto y propenso a error, opté por implementar mi propia función zipObject que siga la vieja convención:

/**
 * Converts [[key0, value0], [key1, value1], ..., [keyN, valueN]]
 * to {key0: value0, key1: value1, ..., keyN: valueN}
 * @param keyValuePairs Array of key-value pairs, where each element is an array of
 *                      two elements [keyi, valuei]
 * @returns An object whose properties are keyi: valuei
 */
Utils.zipObject = function(keyValuePairs) {
  var zippedObject = {};
  for(var i=0; i<keyValuePairs.length; i++) {
    if(keyValuePairs[i] && keyValuePairs[i].length === 2) {
      zippedObject[keyValuePairs[i][0]] = keyValuePairs[i][1];
    }
  };
  return zippedObject;
}

Conclusión

Como en la mayoría de los casos que involucran cambios en la interfaz de una biblioteca, es muy útil tener un conjunto de tests automáticos para poder detectar la mayor cantidad posible de errores introducidos por la migración. En mi caso particular, tenía una suite de tests escritos usando Mocha + Chai + Sinon. Para depurarlos cuando se rompieron, VS Code fue muy útil. Por lo tanto, si no se tiene un conjunto de tests, es recomendable implementar uno que cubra todas las llamadas a Lodash antes de realizar la migración.

En cuanto al uso de Lodash hoy en día, hay quienes proponen eliminar esa dependencia, ya que muchas funciones de Lodash han quedado obsoletas debidos a agregados recientes al estándar ECMA, o Javascript Moderno como algunos lo llaman. Esto es ciertamente un punto a considerar, especialmente si no se usan funciones complejas y exclusivas de Lodash que aún no están en el estándar de JS. Dado que cada función de Lodash está disponible como un paquete npm aislado, una buena opción es reemplazar todos los usos posibles de Lodash con JS moderno, y mantener el resto con referencias al paquete de cada función, evitando así referenciar Lodash completa y reduciendo la huella de memoria de la app.

Comments

Popular posts from this blog

VB.NET: Raise base class events from a derived class

C++/CLI: Convert a String to BSTR or some other nasty stuff

Upgrading Lodash from 3.x to 4.x