Less.js: modificarVars no se pasa

Creado en 23 feb. 2018  ·  6Comentarios  ·  Fuente: less/less.js

Tengo un archivo index.less que decide qué archivo de variables cargar con una variable como esta:

@theme-variant: "a-theme.less";

<strong i="6">@import</strong> "./@{theme-variant}";

Tengo menos archivos que se cargan en ese archivo de índice:

<strong i="10">@import</strong> "~theme-variant-variables";

Estoy configurando un valor para la variable en mi archivo webpack.config.js :

lessOptions.modifyVars = {
   "theme-variant": `"${v}-theme.less"`
}

Si muevo el contenido del archivo index.less a un archivo de menos importado directamente, todo funciona como espero, puedo cambiar el archivo de variables elegido en función de la lógica de configuración del paquete web, lamentablemente si intento centralizar esas dos líneas de menos en un archivo que los archivos importados directamente menos se importan a sí mismos, deja de funcionar. Veo menos llamadas al cargador con la configuración esperada, así que supongo que el compilador menos no propaga variables/opciones a menos archivos importados. ¿Es eso lo esperado?

Todos 6 comentarios

Supongo que esto es lo mismo que en el n.º 2772: vea la mitad de la discusión allí (por ejemplo, modifyVars tiene el efecto de definir la variable, pero viene después de que la instrucción de importación de interés ya se evaluó ). Pero también vea https://github.com/less/less.js/issues/1400#issuecomment -137128461.

En resumen, el punto es: la interpolación de variables dentro de las declaraciones de importación es algo útil, pero entra en conflicto directamente con el principio de evaluación perezosa. Por lo tanto, si se trata de una estructuración compleja, sería mejor encontrar otras formas de lograr este tipo de personalización (por ejemplo, usar diferentes directorios para diferentes archivos de temas y luego configurar la opción paths correspondiente para cambiar).

Gracias por la respuesta. La variable se actualiza en menos archivos que son importados directamente por JS, son solo archivos que son importados por otros menos archivos que no tienen su variable actualizada. ¿La evaluación perezosa está ocurriendo en ambos casos seguramente? Parece que la lógica/configuración de modificación de var no se está aplicando/pasando a los archivos menos importados. ¿O me estoy perdiendo algo?

La variable se actualiza en menos archivos que son importados directamente por JS, son solo archivos que son importados por otros menos archivos que no tienen su variable actualizada.

Bueno, es más complicado que eso. Tenga en cuenta que para que la evaluación perezosa funcione, el compilador tiene que evaluar varias entidades de lenguaje (en el mismo ámbito) por tipos, no por el orden en que aparecen en el código, desde el nivel superior al inferior, es decir (aproximadamente): importaciones -> mixins - > variables.
Ahora, si tiene <strong i="9">@import</strong> "@{var}"; el compilador se ve obligado a evaluar la variable dada antes de la importación (y todas las importaciones posteriores), y esto es lo que arruina todo (en general, el resultado de tal abuso simplemente no está definido). funciona en un caso (en su mayoría muy simple) y no en otros).

No hay forma de que el compilador garantice un comportamiento consistente cuando se combinan dos características directamente conflictivas.

En otras palabras, no es que modifyVars no "actualice las variables" en las importaciones posteriores, sino que los valores de las variables actualizadas no pueden tener ningún efecto en las importaciones de nivel externo (porque estas importaciones ya están "hechas").


E incluso si los documentos dicen:

Tenga en cuenta que antes de v2.0.0, solo se consideraban las variables que se habían declarado en el ámbito raíz o actual y que solo se consideraban el archivo actual y los archivos de llamada al buscar una variable.

... en realidad no es mucho mejor después de v2. Mejoró /arregló más combinaciones/casos de uso, pero no puede arreglarlos todos. Para más detalles ver #1108 y específicamente #2246.


Parece que la lógica/configuración de modificación de var no se está aplicando/pasando a los archivos menos importados.

No (simplemente porque al final los archivos se evalúan todos juntos como una sola cadena grande). A menos que el problema esté en otra parte, para verificar simplemente agregue:
foo {bar: @theme-variant}
a los archivos de interés y ver el resultado.

Por cierto. Para su caso de uso (si "*-theme.less" se trata solo de variables/mixins para un tema específico), puede intentar algo como:

  • Deje el valor predeterminado <strong i="7">@import</strong> "a-theme.less"; para que se explique allí (es decir, sin ninguna interpolación) o elimínelo por completo.
  • Con modifyVars establezca la declaración de importación en sí (por ejemplo <strong i="11">@import</strong> "custom-theme.less"; directamente).

Tenga en cuenta que mientras modifyVars finge que solo se trata de variables bla-bla-bla, de hecho, no hace nada más que agregar un texto arbitrario al final del archivo raíz. Es decir, en el caso de lessc es realmente solo --modify-vars="whatever-less-code foo {bar: baz;}" . Sin embargo, no sé qué formatos puede pasar el cargador menos de webpack, hmm ... ¿ lessOptions.modifyVars = "an arbitrary code"; tal vez?

Eso es obviamente un truco, pero de hecho es un truco bastante predecible (ya que abusa solo del formato modifyVars y no del lenguaje en sí como lo hace el combo inicial).

Muchas gracias por sus respuestas e ideas @seven-phases-max. Voy a investigar más a fondo durante la semana y he configurado un recordatorio para actualizar/cerrar este problema más adelante en la semana. Gracias de nuevo.

Cerraré esto entonces, ya que es más como un comportamiento esperado (definido como "indefinido/no especificado" en este caso) en lugar de un problema que podría solucionarse de alguna manera.
Aunque cualquier idea de mejora y especialmente las relaciones públicas siempre son bienvenidas... No creo que nadie vaya a meterse en esto en un futuro previsible.

¿Fue útil esta página
0 / 5 - 0 calificaciones