Less.js: modifyVars não está sendo transmitido

Criado em 23 fev. 2018  ·  6Comentários  ·  Fonte: less/less.js

Eu tenho um arquivo index.less que decide quais arquivos de variáveis ​​devem ser carregados por uma variável assim:

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

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

Eu tenho menos arquivos que carregam nesse arquivo de índice:

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

Estou definindo um valor para a variável no meu arquivo webpack.config.js :

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

Se eu mover o conteúdo do arquivo index.less para um arquivo menos importado diretamente, tudo funciona como eu esperava, posso alternar o arquivo de variáveis ​​escolhido com base na lógica de configuração do webpack, infelizmente se eu tentar centralizar essas duas linhas de menos em um arquivo que os menos arquivos importados diretamente importam, ele para de funcionar. Eu vejo menos chamadas de carregador com a configuração esperada, então acho que o compilador menos não propaga variáveis/opções para importar menos arquivos. Isso é esperado?

Todos 6 comentários

Suponho que seja a mesma coisa que em #2772 - veja o meio da discussão lá (por exemplo modifyVars tem o efeito de definir a variável, mas vem depois que a declaração de importação de interesse já foi avaliada ). Mas veja também https://github.com/less/less.js/issues/1400#issuecomment -137128461.

Resumindo, o ponto é: a interpolação de variável dentro de instruções de importação é uma coisa útil, mas conflita diretamente com o princípio de avaliação preguiçosa. Assim, se se trata de estruturação complexa, é melhor encontrar outras maneiras de obter esse tipo de personalização (por exemplo, usando diretórios diferentes para arquivos de tema diferentes e, em seguida, configurando a opção paths correspondente para alternar).

Obrigado pela resposta. A variável é atualizada em menos arquivos que são importados diretamente pelo JS, são apenas arquivos que são importados por outros menos arquivos que não têm sua variável atualizada. Avaliação preguiçosa está ocorrendo em ambos os casos, certamente? Parece que a lógica/configuração de modificação de var não está sendo aplicada/passada para os arquivos menos importados. Ou eu estou esquecendo de alguma coisa?

A variável é atualizada em menos arquivos que são importados diretamente pelo JS, são apenas arquivos que são importados por outros menos arquivos que não têm sua variável atualizada.

Bem, é mais complicado do que isso. Observe que para a avaliação lenta funcionar o compilador tem que avaliar várias entidades de linguagem (no mesmo escopo) por tipos e não pela ordem em que aparecem no código, do nível mais alto para o mais baixo, ou seja (aproximadamente): imports -> mixins - > variáveis.
Agora, se você tem <strong i="9">@import</strong> "@{var}"; o compilador é forçado a avaliar a variável dada antes da importação (e todas as importações subsequentes) - e é isso que estraga tudo (em geral o resultado de tal abuso é simplesmente indefinido - é funciona em um casos (principalmente muito simples) e não em outros).

Não há como o compilador garantir qualquer comportamento consistente quando dois recursos diretamente conflitantes são combinados.

Em outras palavras, não é que modifyVars não "atualize variáveis" em importações subsequentes, mas os próprios valores de variáveis ​​atualizados não podem ter nenhum efeito nas importações de nível externo (porque essas importações já estão "concluídas").


E mesmo que os documentos digam:

Observe que antes da v2.0.0, apenas as variáveis ​​que foram declaradas no escopo raiz ou atual eram consideradas e que apenas o arquivo atual e os arquivos de chamada eram considerados ao procurar uma variável.

... não é muito melhor depois da v2. Ele melhorou / corrigiu mais combinações / casos de uso, mas não pode corrigir todos eles. Para mais detalhes, veja o nº 1108 e especificamente o nº 2246.


Parece que a lógica/configuração de modificação de var não está sendo aplicada/passada para os arquivos menos importados.

Não (simplesmente porque no final os arquivos são avaliados todos juntos como uma única string grande). A menos que o problema esteja em outro lugar, para verificar basta adicionar:
foo {bar: @theme-variant}
aos arquivos de seu interesse e veja o resultado.

A propósito. Para o seu caso de uso (se o "*-theme.less" for apenas sobre variáveis/mixins para um tema específico), você pode tentar algo como:

  • Deixe o padrão <strong i="7">@import</strong> "a-theme.less"; para ser explícito lá (ou seja, sem qualquer interpolação) ou remova-o completamente.
  • Com modifyVars defina a própria declaração de importação (por exemplo <strong i="11">@import</strong> "custom-theme.less"; diretamente).

Observe que enquanto modifyVars finge que é apenas sobre variáveis ​​bla-bla-bla - na verdade, ele não faz nada além de anexar um texto arbitrário ao final do arquivo raiz. Ou seja, no caso de lessc é realmente apenas --modify-vars="whatever-less-code foo {bar: baz;}" . Eu não sei que formatos o less-loader do webpack pode passar, hmm... lessOptions.modifyVars = "an arbitrary code"; talvez?

Isso é obviamente um hack, mas na verdade é um hack bastante previsível (já que abusa apenas do formato modifyVars e não do idioma em si, como o combo inicial).

Muito obrigado por suas respostas e ideias @seven-phases-max Vou investigar mais durante a semana e defini um lembrete para atualizar/encerrar esse problema no final da semana. Obrigado novamente.

Vou fechar isso então, pois é mais um comportamento esperado (definido como "indefinido/não especificado" neste caso) do que um problema que poderia ser realmente corrigido de alguma forma.
Embora quaisquer idéias de melhoria e especialmente PRs sejam sempre bem-vindas... Eu não acho que ninguém vai entrar nisso em um futuro próximo.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

chricken picture chricken  ·  6Comentários

seven-phases-max picture seven-phases-max  ·  6Comentários

MarkSG93 picture MarkSG93  ·  4Comentários

xblakestone picture xblakestone  ·  3Comentários

Oskariok picture Oskariok  ·  6Comentários