Como / onde o Magento converte um nome de módulo RequireJS em um URL?

8

No Magento 2, você pode usar o RequireJS para incluir um módulo javascript com código que se parece com isso.

#File: app/code/Package/Name/view/frontend/requirejs-config.js
var config = {
    map: {
        '*': {
            modulename: 'Package_Name/js/path/to/file'
        }
    }
}

Enquanto o requirejs-config.jsarquivo é um pouco de mágica do Magento 2, isso parece ser o RequireJS padrão. Você está basicamente mapeando o nome abreviado modulenamepara o módulo javascript chamado Package_Name/js/path/to/file.

O que não está claro é onde ou como o Magento 2 converte o nome do módulo javascript acima

Package_Name/js/path/to/file

No URL HTTP (S)

//magento.example.com/static/frontend/Magento/luma/en_US/Package_Name/js/path/to/file.js

Em um sistema RequireJS em estoque, o RequireJS tentaria carregar o seguinte URL

//magento.example.com/Package_Name/js/path/to/file.js

Tão claramente que o Magento está fazendo algo para garantir que o URL acima seja convertido em um URL de front-end do Magento. O que não está claro é

  1. Onde isso acontece (camada PHP? Camada Javascript?)
  2. Qual é a regra para essa conversão. O módulo RequireJS não se parece com um identificador de arquivo Magento padrão ( Package_Name::js/path/to/file)

Então, como / onde o Magento 2 / RequireJS converte o módulo em um caminho.

Alan Storm
fonte

Respostas:

7

O RequireJS possui um recurso que permite definir um baseUrl personalizado .

O Magento gera baseUrl para RequireJS no corpo da página, onde os recursos JS são solicitados. Portanto, é basicamente mais uma parte da configuração do RequireJS gerada pelo Magento. Este baseUrl é calculado no lado do servidor e é baseado no tema atual, código de idioma e URL base para arquivos de exibição estática do armazenamento. A funcionalidade RequireJS nativa calcula o caminho completo da seguinte maneira

baseUrl + file + '.js'
BuskaMuza
fonte
Isso não parece responder à pergunta que fiz.
Alan Storm
Você poderia, por favor, esclarecer a questão? O Magento apenas usa o recurso RequireJS de baseUrl- requirejs.org/docs/api.html#config-baseUrl e, para fazê-lo funcionar corretamente, gera o baseUrlmesmo valor //magento.example.com/static/frontend/Magento/luma/en_US/da página. O RequireJS apenas concatena com o caminho do módulo: //magento.example.com/static/frontend/Magento/luma/en_US/ + Package_Name/js/path/to/file -> //magento.example.com/static/frontend/Magento/luma/en_US/Package_Name/js/path/to/filee adiciona .js.
precisa saber é o seguinte
Informações úteis @BushaMuza, mas, novamente, não é a pergunta que eu fiz.
Alan Storm
11
Eu acho que é RequireJS baunilha. Se a tag 'data-main' estiver definida (que é o M2 padrão), ela adicionará o baseUrl que está sendo definido no arquivo que o BuskaMuza faz referência na frente do URL JS mapeado. O baseUrl está definido para a pasta estática (com localidade), que é, por exemplo //magento.example.com/static/frontend/Magento/luma/en_US/. Adicione Package_Name/js/path/to/file.jsa ele e você terá o URL completo. Eu acho que isto é o que você está procurando; github.com/magento/magento2/blob/develop/lib/web/requirejs/…
Peter Jaap Blaakmeer
7

Você está se perguntando como

Module_Name/js/path/to/module

torna-se

//magento.example.com/static/frontend/Package/Theme/locale/Module_Name/js/path/to/module.js

Antes de tudo, é importante entender que isso é totalmente necessário para o JS, não para qualquer molho especial do Magento (embora exista um pouco disso em outro lugar). Na maioria das vezes, o front-end usa apenas o comportamento normal do RequireJS. A mágica geralmente está na forma como gera pub/static, ou seja, como view/area/web/js/path/to/module.jsé simbolizado pub/static/area/Package/theme/Module_Name/js/path/to/module.js. Isso é tratado pelo processo de compilação de ativos estáticos do Magento, e eu não vou entrar aqui.

requirejs-config.js

Vamos introduzir um novo arquivo, que você menciona: requirejs-config.js. Este é um molho especial do Magento 2, mas provavelmente não tanto quanto você imagina.

Esse arquivo pode ser qualquer JavaScript, mas deve, no mínimo, declarar uma variável (global) chamada config. O objeto vinculado a configé passado diretamente para exigir que o JS o configure.

A maneira como isso funciona é que o Magento encontra tudo isso requirejs-config.jsem um projeto. Eles podem estar em um módulo, sob view/areaou em um tema, em seu diretório raiz e na substituição do módulo de um tema, por exemplo Magento_Catalog/requirejs-config.js. Observe que isso não inclui nenhum filho de um webdiretório. Esse arquivo, em geral, deve ser um irmão de um webdiretório.

Uma vez globbed, cada arquivo é decorado com um fechamento (portanto, nossa variável global não é) e uma linha no final do fechamento passa a configvariável para o requireobjeto. Isso pode ser visto:

Isto é Magento_Checkout::view/frontend/requirejs-config.js:

/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

 var config = { 
 map: { 
 '*': { 
 discountCode: 'Magento_Checkout/js/discount-codes',
 shoppingCart: 'Magento_Checkout/js/shopping-cart', 
 regionUpdater: 'Magento_Checkout/js/region-updater', 
 opcOrderReview: 'Magento_Checkout/js/opc-order-review',
 sidebar: 'Magento_Checkout/js/sidebar', 
 payment: 'Magento_Checkout/js/payment', 
 paymentAuthentication: 'Magento_Checkout/js/payment-authentication' 
 }
 } 
};

Quando chega ao front-end, fica assim:

(function() {
 /**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

 var config = { 
 map: { 
 '*': { 
 discountCode: 'Magento_Checkout/js/discount-codes',
 shoppingCart: 'Magento_Checkout/js/shopping-cart', 
 regionUpdater: 'Magento_Checkout/js/region-updater', 
 opcOrderReview: 'Magento_Checkout/js/opc-order-review',
 sidebar: 'Magento_Checkout/js/sidebar', 
 payment: 'Magento_Checkout/js/payment', 
 paymentAuthentication: 'Magento_Checkout/js/payment-authentication' 
 }
 } 
}; require.config(config);
})();

Esta decoração pode ser vista em Magento\Framework\RequireJs\Config.

Cada um desses arquivos decorados é concatenado e despejado static/_requirejs/area/Package/theme/locale/secure/requirejs-config.js. Esse local é acordado com antecedência, para que o HTML carregue esse script à medida que o requireJS:

<script type="text/javascript" src="https://magento.example.com/static/area/Package/theme/locale/requirejs/require.js"></script> <script type="text/javascript" src="https://magento.example.com/static/_requirejs/area/Package/theme/locale/secure/requirejs-config.js"></script>

Considero como configurar o RequireJS fora do escopo para esta resposta, mas eles têm uma documentação bastante boa sobre isso . Há duas coisas importantes a serem observadas:

  1. Chamadas sucessivas require.configcolocarão objetos sobrepostos, para que a última gravação ganhe. Eles não substituem, o que é crucial.
  2. Há uma configuração na parte superior desta configuração que define baseUrl. Isto não está em um requirejs-config.js. Isso é inserido no momento da compilação por Magento\Framework\RequireJs\Config.

Esquecendo por um momento como o Magento descobre quais módulos do RequireJS precisam ser carregados (uma boa discussão para outra hora, talvez; como sugestão, veja mage/apply/main.js), vamos supor que temos o código:

require(['modulename'], function () {});

no vácuo em algum lugar. Como o Magento sabe o que fazer?

Bem, a primeira coisa que o requireJS fará é procurar modulenameem seu mapeamento. No nosso caso, ele aprenderá que deve tratar todos os pedidos modulenamecomo um pedido para Module_Name/js/path/to/module. Só faz isso uma vez. Os mapeamentos não são recursivos. Eu repito. Se você tiver um mapeamento de apara be de bpara a, isso trocará cada solicitação e não causará um loop infinito.

Depois de analisarmos o mapeamento, o RequireJS analisa o que ele possui. Se ele terminar .jse não parecer um link absoluto ou uma URL, ele acrescentará o baseUrlscript configurado e carregará esse script através de seus procedimentos normais. Se ele não terminar .jse não for um link ou URL absoluto, será adicionado .jsao final e, em seguida, anteceda a configuração baseUrle carregue seus procedimentos normais. Se o requireJS considerar que possui uma URL, apenas tentará carregá-la.

Max Bucknell
fonte
OK, eu tenho esse. A peça que faltava para mim era a configuração baseUrl do RequireJS. ou seja, "RequireJS possui um recurso que permite definir um baseUrl personalizado, o Magento usa esse recurso e gera o baseURL nesse backend" requirejs.org/docs/api.html#config-baseUrl
Alan Storm
0

Ele está usando componentes com mais detalhes. Verifique a classe Magento \ Framework \ View \ Element \ Js \ Components e defaul vendor arquivo de módulo \ magento \ catalog-module \ view \ frontend \ layout \ default.xml

<referenceContainer name="after.body.start">
        <block class="Magento\Framework\View\Element\Js\Components" name="head.components" as="components" template="Magento_Catalog::js/components.phtml"/>
    </referenceContainer>
Pratik
fonte
Isso não parece responder à pergunta que fiz.
Alan Storm