Next.js: Solicitação de recurso: suporte Basepath

Criado em 21 ago. 2018  ¬∑  73Coment√°rios  ¬∑  Fonte: vercel/next.js

Solicitação de recurso

Sua solicitação de recurso está relacionada a um problema? Por favor descreva.

Multi-zonas é um ótimo recurso que permite executar vários aplicativos next.js no mesmo domínio, mas não permite definir um caminho de base que será aceito por todas as partes de next.js. Como não podemos atribuir nomes a aplicativos no momento, não é possível ter os mesmos nomes para páginas em vários aplicativos.

Descreva a solução que você gostaria

Quero ser capaz de configurar um basepath no arquivo next.config.js. Graças a esta configuração, todas as partes de next.js (roteador, link, ativos estáticos, etc.) reconhecerão o caminho de base e serão automaticamente gerados e correspondentes aos caminhos corretos.

Descreva as alternativas que você considerou

Uma alternativa é aninhar todas as páginas desejadas em uma pasta que corresponda ao caminho de base. Isso resolve apenas um pequeno problema com o roteamento e é muito feio porque a maioria dos meus caminhos de base não são caminhos de um nível.
A segunda alternativa é configurar um proxy de forma que o caminho de base seja removido automaticamente antes que a solicitação chegue em um aplicativo next.js e também implementar um componente Link personalizado que adiciona automaticamente o caminho de base a todos os links. Só não quero manter o fork personalizado do next.js. Não faz sentido na minha opinião.

Contexto adicional

A solução assetPrefix nos permite definir um prefixo diferente para cada aplicativo. Mas, pelo que sei, só funciona com hosts diferentes.

exemplo com zonas

module.exports = {
  assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:4000'
}

Se eu adicionar um caminho de base a ele, tudo falhar√°

module.exports = {
  assetPrefix: NOW_URL ? `https://${alias}/account` : 'http://localhost:4000/account'
}

screen shot 2018-08-21 at 10 47 08

Na minha opini√£o, devemos dividi-lo em 2 vari√°veis:

module.exports = {
  assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:4000',
  basepath: '/account'
}

Assuntos relacionados

story needs investigation

Coment√°rios muito √ļteis

Qualquer atualiza√ß√£o sobre isso ... no ano passado, nessa √©poca, me deparei com esse problema. Agora, um ano depois, estou trabalhando em um novo aplicativo e tenho que fazer as mesmas solu√ß√Ķes alternativas que fiz no ano passado ... um pouco alarmante para uma rea√ß√£o "pronta para produ√ß√£o". Os caminhos de base devem ser uma caracter√≠stica comum.

Não tenho certeza do que você espera ao postar isso.

Next.js est√° sendo trabalhado em tempo integral pela minha equipe (5 pessoas), e estamos trabalhando em muitos recursos ao mesmo tempo. No ano passado, trabalhamos nisso:

Tornando eficazmente os aplicativos Next.js (novos e existentes) significativamente menores, mais r√°pidos e mais escal√°veis.

Se voc√™ quiser expressar seu "voto positivo" para um recurso, pode. use o recurso ūüĎć no thread inicial.

Eu definitivamente concordo que basePath deve ser um recurso integrado. Já está no roteiro e eu até escrevi um PR inicial, que você poderia ter visto lendo o tópico.

Aqui est√° o PR: https://github.com/zeit/next.js/pull/9872

Sinta-se √† vontade para entrar em contato com [email protected] se desejar contribuir financeiramente para que esse recurso aconte√ßa.

Todos 73 coment√°rios

cc @jxnblk

cc @alexindigo @DullReferenceException

Adoraria receber seu feedback ūüĎć

Depois de brincar com o código, percebi que seria muito mais fácil dividir assetPrefix em várias partes:

module.exports = {
  host: NOW_URL ? `https://${alias}` : 'http://localhost:3000',
  basePath: '/account',
}

Ainda podemos manter a vari√°vel assetPrefix internamente, mas o usu√°rio deve definir mais precisamente o que precisa.

Para a parte do ativo, √© muito bom fornecer essas duas vari√°veis ‚Äč‚Äčjuntas.
Para roteamento, etc, precisamos deles separadamente.
Ou talvez possamos até mesmo fornecê-lo juntos em um arquivo de configuração e então dividi-lo na base de código next.js. Neste caso, assetPrefix não é o nome certo, infelizmente.

Como um efeito colateral, isso tamb√©m leva a menos altera√ß√Ķes no c√≥digo.
√Č bastante √≥bvio se voc√™ comparar esses dois PRs:
https://github.com/panter/next.js/pull/2 (dividir)
https://github.com/panter/next.js/pull/1 (passar em ambos)

Na minha opinião, eles devem ser separados, a razão para isso é que não é quebrável e mais flexível manter assetPrefix e ter basePath separadamente.

Ent√£o assetPrefix o nome certo? Ambas as vari√°veis ‚Äč‚Äčs√£o na verdade um prefixo, certo?

assetPrefix é para ativos, por exemplo: os pacotes de páginas. basePath será para o roteador.

A maneira como deve funcionar é:

  • se assetPrefix for definido, use assetPrefix para carregar os pacotes, n√£o toque no roteador (comportamento atual)
  • se assetPrefix e basePath forem fornecidos, use assetPrefix para carregar pacotes, adicione basePath ao roteador
  • se assetPrefix n√£o estiver definido e basePath estiver, use basePath para carregar pacotes e adicione basePath ao roteador
  • se nem assetPrefix nem basePath s√£o definidos, n√£o fazemos nada diferente (comportamento atual quando assetPrefix n√£o √© fornecido)

cc @alexindigo @DullReferenceException @ 3rd-Eden

Você poderia dar um feedback sobre a proposta acima: https://github.com/zeit/next.js/issues/4998#issuecomment -414978297

@tomaswitek Não tenho certeza do que exatamente não funcionou para você com o assetPrefix atual, este é o prefixo de ativo que estamos usando na produção: "assetPrefix":"https://static.trulia-cdn.com/javascript" e funciona conforme o esperado.

E, em geral, estamos usando várias zonas (nós as chamamos de ilhas) no mesmo domínio e "basePathing" cada ilha nunca veio à nossa mente, pois isso complicaria a interoperabilidade entre as ilhas. Deixe-me explicar um pouco mais:

Portanto, temos duas ilhas A e B , e a ideia principal com elas √© a transpar√™ncia para os usu√°rios que navegam de ilha em ilha como parte de sua experi√™ncia de um site. Portanto, deve haver liga√ß√Ķes entre as ilhas. Depois, h√° preocupa√ß√£o com a implanta√ß√£o versus preocupa√ß√£o com o aplicativo.

  1. Preocupa√ß√£o com a implanta√ß√£o x preocupa√ß√£o com o aplicativo - o aplicativo n√£o tem ideia de onde poderia ser implantado, apenas sabe como lidar com as solicita√ß√Ķes HTTP recebidas - ele definiu as rotas √†s quais pode responder.
    Quando ele é implantado em algum lugar - podem ser domínios diferentes, portas diferentes e, sim, teoricamente, pode ser basePath diferente, que será transparente para o aplicativo via proxy ou outros meios.

  2. Liga√ß√Ķes cruzadas entre as ilhas - para manter o esp√≠rito das ilhas como entidades implant√°veis ‚Äč‚Äčseparadas, n√£o deve haver nenhum vazamento de conhecimento interno de implementa√ß√£o entre as diferentes ilhas.
    Portanto, a melhor maneira de as ilhas referenciarem as páginas umas das outras é exportar as rotas disponíveis para consumo de outra (s) ilha (s) (_e no mundo seguinte, parece que os componentes de <IslandALink> seriam os caminho_).
    At√© agora, √© tudo simples - todas as ilhas assumem que compartilham o mesmo dom√≠nio e t√™m seu conjunto de caminhos absolutos ( /path1 , path2 , etc). Dessa forma, a segunda ilha importa essa lista de caminhos e depende dela para ser est√°vel. Ao mesmo tempo, √© um requisito m√≠nimo para cada ilha manter seus caminhos compat√≠veis com vers√Ķes anteriores (o que √© bom na web de qualquer maneira) :)

Quando adicionamos basePath específico de implantação, aumentamos automaticamente a complexidade de todo o sistema - cada ilha deve saber (e talvez ditar) seu próprio basePath de implantação? Então, como isso é diferente da maneira como as coisas funcionam atualmente? Ou a ilha A deve ser agnóstica quanto ao seu caminho de implantação? Então como a ilha B encontrará implantada a ilha A, já que ela só sabe o que a ilha A conhece sobre si mesma? Ou você teria que fornecer basePath para todas as ilhas implantadas para todas as outras ilhas? E com uma maneira moderna de implantar coisas, isso significa redistribuir todas as ilhas quando você precisar adicionar uma nova.

Ou como você imaginou essa parte da história?

Obrigado.

^ foi escrito antes do café da manhã, então, por favor, deixe-me saber se você precisar de uma explicação mais coerente para qualquer parte dele. :)

Em primeiro lugar, agradeço a vocês por analisarem meu problema.

@timneutkens Sim assetPrefix tem prioridade sobre basePath , isso é exatamente o que discutimos no início. Depois de ver quantos arquivos eu tinha que alterar, pensei que a segunda maneira seria mais limpa. Mas vou voltar para a primeira solução. Vamos mantê-lo totalmente separado, sem nenhum problema. Eu estava pensando alto.

@alexindigo Thx pela sua resposta detalhada. Deixe-me tentar responder √†s suas perguntas ūüėŹ

Não tenho certeza do que exatamente não funcionou para você com o assetPrefix atual

Tenho dois problemas aqui:

  1. N√£o consigo trabalhar com v√°rios dom√≠nios nem subdom√≠nios no projeto atual. (Restri√ß√Ķes de dom√≠nio e nenhum certificado SSL curinga)
  2. A implementa√ß√£o atual de assetPrefix em um √ļnico dom√≠nio requer mais ajustes no roteamento de proxy, arquivos est√°ticos, etc. Poder√≠amos reduzir esses ajustes introduzindo basePath . Isso n√£o vai travar nada e n√£o vai aumentar a complexidade porque voc√™ n√£o precisa fornecer basePath como @timneutkens j√° mencionado.

aplicativo n√£o tem ideia de onde poderia ser implantado

Temos o mesmo objetivo aqui, é claro! Estamos definindo assetPrefixes dinamicamente na solução atual que temos. Ele é fornecido por meio de cabeçalhos de solicitação por proxy.

Então, como isso é diferente da maneira como as coisas funcionam atualmente?

O roteador estará ciente do contextPath e reduzirá a quantidade de código personalizado.

cada ilha deve saber (e talvez ditar) sua própria implantação basePath? Ou a ilha A deve ser agnóstica quanto ao seu caminho de implantação?

Não tem que ser. O desenvolvedor deve ter liberdade aqui. Deve ser possível fornecer basePath dinamicamente da mesma forma que assetPrefix.

Então como a ilha B encontrará implantada a ilha A, já que ela só sabe o que a ilha A conhece sobre si mesma? Ou você teria que fornecer basePath para todas as ilhas implantadas para todas as outras ilhas? E com uma maneira moderna de implantar coisas, isso significa redistribuir todas as ilhas quando você precisar adicionar uma nova.

Talvez voc√™ tamb√©m possa adicionar o basePath na exporta√ß√£o de rotas. Eu n√£o sei. N√£o estou dizendo que a vari√°vel basePath √© importante para todos os casos de uso. Parece que n√£o √© a melhor solu√ß√£o para voc√™. Mas tudo bem. O fato √© que voc√™ ainda pode usar apenas assetPrefix e nada mudar√° para suas ilhas. Parece que voc√™ tem seu pr√≥prio roteamento. As liga√ß√Ķes cruzadas entre as zonas nem mesmo s√£o importantes para o nosso projeto, nossas zonas s√£o realmente independentes e isoladas umas das outras.

E com uma maneira moderna de implantar coisas, isso significa redistribuir todas as ilhas quando você precisar adicionar uma nova.

Não vejo razão para isso. Posso até imaginar que algumas zonas têm basesPaths e outras não. E talvez alguns aplicativos usem a configuração do basePath mesmo sem a configuração de várias zonas.

@alexindigo, voc√™ poderia nos fornecer dois urls de ilha reais, que s√£o renderizados por next.js para que eu pudesse v√™-los em a√ß√£o? Tentei encontrar um, mas n√£o consegui encontrar uma p√°gina em seu dom√≠nio com _next solicita√ß√Ķes ūüėĄ
Todas as suas ilhas têm a mesma configuração?
"assetPrefix":"https://static.trulia-cdn.com/javascript"

@tomaswitek

N√£o consigo trabalhar com v√°rios dom√≠nios nem subdom√≠nios no projeto atual. (Restri√ß√Ķes de dom√≠nio e nenhum certificado SSL curinga)

Ah, então você não usa o CDN no sentido clássico, mas confia nos ativos sendo buscados diretamente em cada aplicativo? Eu vejo.

A implementa√ß√£o atual do assetPrefix em um √ļnico dom√≠nio requer mais ajustes no roteamento de proxy, arquivos est√°ticos, etc. Poder√≠amos reduzir esses ajustes introduzindo o basePath. Isso n√£o vai travar nada e n√£o vai aumentar a complexidade porque voc√™ n√£o precisa fornecer o basePath como @timneutkens j√° mencionado.

Aliás, não era "não, não adicione esse recurso" :) Foi mais como - "Provavelmente podemos pensar sobre essa abordagem de forma mais holística" :)

Não tem que ser. O desenvolvedor deve ter liberdade aqui. Deve ser possível fornecer basePath dinamicamente da mesma forma que assetPrefix.

Sim. No entanto, s√≥ funciona quando n√£o existe liga√ß√£o entre as ilhas. E parece que este √© o seu caso de uso. Ao mesmo tempo, estou tendo dificuldade em entender o que os torna ilhas em vez de apenas um monte de aplicativos aut√īnomos, se eles s√£o 100% independentes? :)

Talvez você também possa adicionar o basePath na exportação de rotas.

Não sei como isso poderia ser feito (facilmente), uma vez que a exportação de rotas acontece no momento da construção, e o basePath sendo definido no momento da implantação, e pode haver mais de uma implantação do mesmo artefato de código (estágio, pré-produção, produção, env de teste, etc).


Todas as suas ilhas têm a mesma configuração?
"assetPrefix": " https://static.trulia-cdn.com/javascript "

Sim, todas as ilhas compartilham seus ativos, j√° que a seguir faz o hashing de conte√ļdo, n√£o √© apenas um problema, mas na verdade muito ben√©fico. (Extra√≠mos ativos constru√≠dos de cada artefato e publicamos no CDN no momento da implanta√ß√£o).

E dessa forma, temos apenas solicita√ß√Ķes "html regulares" para nossos servidores de aplicativos, √© por isso que n√£o vejo nenhum caminho "_next" em trulia.com

Quanto aos exemplos das ilhas:

Nossa nova ilha - página de bairros - https://www.trulia.com/n/ca/san-francisco/pacific-heights/81571 (e você pode encontrar mais deles aqui: http: //www.trulia. com / bairros)
Esta ilha é responsável por todos os /n/* caminhos.

E outra ilha é nossa página de login - https://login.trulia.com/login - parece um domínio diferente, mas realmente não é, parece assim por diferentes motivos, mas tecnicamente é a mesma implantação. :)
E esta ilha lida com urls como /login , /signup .

Deixe-me saber se você tem mais perguntas.

@alexindigo muito obrigado por seus exemplos.
Tenho algumas perguntas depois de analisar os exemplos ūüėĄ

Você ainda faz a renderização do servidor para cada ilha, mas tenta extrair o máximo de ativos possíveis em um CDN comum, certo?

Por favor, você pode descrever um pouco mais o que exatamente acontece quando https://www.trulia.com/n/ca/san-francisco/pacific-heights/81571 é chamado? Seu proxy sabe que /n significa visão geral da vizinhança e o encaminha para a ilha certa? Isso afeta de alguma forma o pedido antes de chegar à ilha?

Você usa o roteamento integrado próximo a uma ilha ou tem uma solução personalizada?
Queria verificar o roteamento dentro de sua ilha. Infelizmente Neighborhood overview tem mais ou menos navegação modal sem alterar o url. No Login, parece haver uma solução totalmente personalizada.

Espero responder a todas as suas perguntas neste coment√°rio ūüėŹ

Aliás, não era "não, não adicione esse recurso" :) Foi mais como - "Provavelmente podemos pensar sobre essa abordagem de forma mais holística" :)

Claro, seria √≥timo encontrar uma solu√ß√£o onde eu n√£o precise tocar em next.js ūüėŹ

Sim. No entanto, s√≥ funciona quando n√£o existe liga√ß√£o entre as ilhas. E parece que este √© o seu caso de uso. Ao mesmo tempo, estou tendo dificuldade em entender o que os torna ilhas em vez de apenas um monte de aplicativos aut√īnomos, se eles s√£o 100% independentes? :)

Nunca escrevi nem disse que procuro uma solu√ß√£o "ilha". Acabei de bater um papo com next.js n√£o oferece suporte a caminhos de base. E depois de pesquisar um pouco no Google, percebi que n√£o sou o √ļnico procurando por ele. Ent√£o achei que poderia contribuir um pouco. Depois disso, Tim enviou um ping para voc√™ para me dar um feedback e estou muito grato por seus coment√°rios.

Não sei como isso poderia ser feito (facilmente), uma vez que a exportação de rotas acontece no momento da construção, e o basePath sendo definido no momento da implantação, e pode haver mais de uma implantação do mesmo artefato de código (estágio, pré-produção, produção, env de teste, etc).

Bem, se voc√™ deseja exportar rotas em tempo de constru√ß√£o e torn√°-las dispon√≠veis para outras ilhas, ent√£o a √ļnica maneira direta √© provavelmente codificar o basePath na configura√ß√£o. Eu entendi seu ponto. Por outro lado, isso √© realmente um problema? Voc√™ ainda pode implantar o aplicativo em diferentes dom√≠nios e portas e pode usar o mesmo basePath para cada env.

Bom dia @tomaswitek :)

Minha experiência com a funcionalidade "basePath" engana muito em sua complexidade, e geralmente é melhor implementar esse tipo de coisa sem me precipitar com um problema específico,
mas olhando de v√°rios √Ęngulos. Semelhante a como voc√™ abordaria a fus√£o profunda - descreva v√°rios casos de uso e veja como (e se) todos eles se enquadram no mesmo guarda-chuva. J√° que ter recursos incompat√≠veis entre (mesmo as principais) vers√Ķes do framework √© muito chato :)

Você ainda pode implantar o aplicativo em diferentes domínios e portas e pode usar o mesmo basePath para cada env.

Parece que voc√™ concordaria com a solu√ß√£o em que "basePath" faz parte do seu c√≥digo de roteamento, algo que voc√™ mencionou no in√≠cio - como uma subpasta dentro do diret√≥rio pages (ali√°s, essa abordagem seria um sinal para os desenvolvedores escolhidos basePath muito bem). Mas a √ļnica coisa que o impediu √© que o pr√≥ximo caminho interno para os ativos _next n√£o √© configur√°vel.

E isso soa como um problema mais estreito que podemos resolver com menos efeitos colaterais de longo prazo.

E pode nos levar ainda mais longe, como se pudéssemos configurar assetPath por ativo (por exemplo, com o mapa next.config de algum tipo) - isso nos permitirá ter ativos compartilhados entre os aplicativos, o que melhorará o desempenho, e outras coisas.

E h√° rela√ß√Ķes p√ļblicas abertas para esse recurso. ;) / cc @timneutkens parece que √© hora de voltar para aquele cachorro. :)

Se você não vai adicionar isso em breve, poderíamos obter um server.js baseado em express de exemplo adicionado ao readme que faça isso e funcione? Tentei alguns que estão circulando nesses problemas, mas não consegui fazê-los funcionar. Obrigado.

Olá @ccarse , tenho um fork em funcionamento que já usamos na produção: https://github.com/panter/next.js/pull/2
Também estou pronto para investir tempo para abrir um PR para esse recurso.
@timneutkens @alexindigo existe outra maneira de resolver este problema?
Se não precisarmos de uma configuração basePath , você pode nos dar um exemplo mínimo usando assetPath ?

Minha empresa também está enfrentando isso.

Aos poucos, estamos assumindo o controle de um aplicativo legado, seção por seção, e substituindo-o por Next.js.

Como um exemplo simplificado:

| URL | App |
| --- | --- |
| example.com | legado |
| example.com/shop | próximo |
| example.com/search | legado |
| example.com/members | próximo |

Isso significa que queremos que tudo seja prefixado em cada aplicativo Next.js ... P√°ginas, rotas, ativos, etc.

√Č importante notar tamb√©m que n√£o estamos usando agora, por isso n√£o podemos tirar proveito de now.json roteamento. Temos nosso pr√≥prio balanceador de carga na frente de todo o dom√≠nio e, em seguida, roteamos o tr√°fego com base no subcaminho.

Também estamos usando um servidor personalizado (hapi), então seria bom se pudéssemos aproveitar o que quer que seja criado aqui dentro de um servidor personalizado também.

Talvez haja alguma combina√ß√£o de configura√ß√Ķes now.config.json ou algum uso de micro-proxy que possamos usar para realizar essa mesma coisa, mas ainda n√£o descobrimos a combina√ß√£o certa.

Estamos enfrentando, eu acho, o mesmo problema com v√°rios aplicativos Next.js exportados estaticamente e hospedados no Now v2.

| URL | App |
| - | - |
| example.com | próximo |
| example.com/dashboard | próximo |

Como esperado, o aplicativo root funciona bem. As coisas d√£o errado no segundo, no entanto. No momento, estamos empacotando next/link que, combinado com assetPrefix , resolve a maior parte do problema:

export default ({ children, href, ...rest }) => (
      <Link href={process.env.NODE_ENV === "production" ? `/dashboard${href}` : href} {...rest}>
        {children}
      </Link>
);

No entanto, isso quebra prefetch porque tenta procurar .js arquivos no URL errado:

Nossa solução alternativa atual é desativar prefetch , o que não é o ideal.

Qual é o status disso?

Também estou procurando uma atualização sobre isso, por favor.

@timneutkens Estou pronto para investir tempo para abrir um PR, se a comunidade estiver interessada. Já estamos usando uma solução (https://github.com/panter/next.js/pull/1) em produção e estamos muito felizes com ela.

Também precisamos de uma solução para isso

Em breve apresentaremos uma nova API que tornar√° esta proposta obsoleta.

Também impactado por isso. Precisa executar o próximo projeto em um caminho de subdiretório. Ansioso para o recurso oficial. Existe um HEC?

API

Ent√£o, como vai? : D

N√£o envie spam para o t√≥pico e use o recurso ūüĎć do GitHub no problema em si.

@timneutkens Voc√™ pode fornecer mais informa√ß√Ķes? Qual √© a API que tornar√° isso obsoleto? O que voc√™ considera "em breve"? Obrigado.

Isso pode n√£o estar exatamente relacionado a zonas m√ļltiplas, mas pode ajudar ...

Resolvi algo semelhante a isso criando um servidor personalizado e usando middleware de proxy

por exemplo: @Zertz
Observação: você ainda precisa resolver o problema do link - novamente, resolvi isso criando um componente de link e passando o prefixo para o aplicativo via configuração e, se houver um prefixo, use-o ou não use nada, o mesmo para imagens estáticas.

const proxy = require('http-proxy-middleware');

app.setAssetPrefix('/dashboard');

  // Express custom server
  // Proxy so it works with prefix and without...
  // So if asset prefix is set then it still works
  const server = express();
  server.use(
    proxy('/dashboard', {
      target: 'http://localhost:3000', 
      changeOrigin: true,
      pathRewrite: {
        [`^/dashboard`]: '',
      },
    }),
  );

A proposta que mencionei é # 7329

A proposta que mencionei é # 7329

@timneutkens
Você pode fornecer mais detalhes sobre como o gancho proposto resolverá nossos problemas de caminho de base?
E os redirecionamentos de roteador como Router.push('/about') também serão substituídos por um gancho?

Obrigado pelo seu tempo ūüėŹ

A API do roteador também mudaria, pois precisaria de um componente para o link. Nesse ponto, você pode usar caminhos relativos para o próprio url.

Alguma atualização sobre quando podemos obter uma solução ou pelo menos uma solução alternativa para isso?

Use ūüĎć na edi√ß√£o inicial em vez de postar qualquer atualiza√ß√£o.

@ MMT-LD Sua solu√ß√£o meio que funciona para mim, mas agora a cada clique de link ou evento de envio de roteador a p√°gina √© recarregada ‚ėĻÔłŹ

Tentei a solução de @Zertz e funcionou perfeitamente!
Também poderia corrigir prefetch problema copiando arquivos de saída para os caminhos pré-buscados.
https://github.com/fand/MDMT/blob/master/scripts/copy-preload.js

... √© um truque sujo, mas est√° funcionando de qualquer maneiraūü§™

@nicholasbraun

Agora, a cada clique de link ou evento de envio de roteador, a p√°gina √© recarregada ‚ėĻÔłŹ

Tive esse problema, mas resolvi usar o par√Ęmetro 'as' no link, ent√£o o link aponta para o arquivo interno, mas o 'as' √© relativo ao caminho
por exemplo:
<Link href={"/${item.link}"} as={"./${item.link}"}>

@nicholasbraun

Sua solu√ß√£o meio que funciona para mim, mas agora em cada clique de link ou evento de envio de roteador, a p√°gina √© recarregada ‚ėĻÔłŹ

Isso é o que eu quis dizer. Isso é de memória ... mas tenho certeza de que você não pode obter o que precisa a partir de baixo.

// WithConfig component
import getConfig from 'next/config';

const { publicRuntimeConfig } = getConfig();

const WithConfig = ({ children }) =>
  children && children({ config: publicRuntimeConfig });

export default WithConfig;
// Extended Link component

 import React from 'react';
import PropTypes from 'prop-types';
import Link from 'next/link';
import { WithConfig } from '../WithConfig';
/* 
    <Link> component has two main props:
    href: the path inside pages directory + query string. e.g. /page/querystring?id=1
    as: the path that will be rendered in the browser URL bar. e.g. /page/querystring/1

*/

const NextLink = ({
  browserHref,
  pagesHref,
  whatever,
}) => {
  return (
    <WithConfig>
      {({ config: { pathPrefix } = {} }) => (
        <Link
          as={pathPrefix ? `${pathPrefix}${browserHref}` : browserHref}
          href={pagesHref}
          passHref
        >
          <a>{whatever}</a> // this bit is up to you - children or whatever
        </Link>
      )}
    </WithConfig>
  );
};

NextLink.propTypes = {
  browserHref: PropTypes.string.isRequired,
  pagesHref: PropTypes.string,
};

NextLink.defaultProps = {
  pagesHref: undefined,
};

export default NextLink;

Uso:

import NextLink from '../NextLink'

<NextLink browserHref={`/page/1`} pagesHref={`/page?querystring=1`} whatever='I'm the link' />

Boa sorte: smiley:

Como o useLink RFC foi recusado (# 7329) e ter basePath suporte nos ajudaria muito, o projeto Next.js est√° feliz em aceitar PRs implementando-o? Estou disposto a fazer isso.

Olhando para esta implementação de @tomaswitek , ela parece estar indo na direção certa, o mais importante é alertar o roteador sobre basePath . Existem outras coisas não óbvias que tornariam o suporte de basePath difícil?

No geral, acho que o design √© claro, apenas uma √ļnica vari√°vel de configura√ß√£o:

module.exports = {
  basePath: '/demo'
}

As intera√ß√Ķes com assetPrefix est√£o bem definidas aqui: https://github.com/zeit/next.js/issues/4998#issuecomment -414978297.


ATUALIZAÇÃO : Eu também estava pensando se seria possível implementar isso criando um roteador personalizado e de alguma forma trocando o padrão, mas não parece ser possível, Next.js codifica seu roteador, veja, por exemplo, aqui . Também estou cético de que "apenas" substituir o roteador seria suficiente; o recurso provavelmente precisa ser suportado por Next.js como um todo.

Este problema existe desde 2017, existe alguma solução alternativa? Ou uma resposta oficial à nossa solicitação de basePath?

Então, depois de tentar fazer isso funcionar com a combinação de assetPrefix e um componente <Link> , conforme sugerido em, por exemplo, https://github.com/zeit/next.js/issues/4998#issuecomment -464345554 ou https://github.com/zeit/next.js/issues/4998#issuecomment -521189412, não acredito que possa ser feito, infelizmente.

Definir assetPrefix foi relativamente simples, algo assim em next.config.js :

const assetPrefix = process.env.DEPLOYMENT_BUILD ? '/subdir' : '';

module.exports = {
  assetPrefix,
  env: {
    ASSET_PREFIX: assetPrefix,
  },
}

A próxima etapa é um componente Link . A primeira idéia, dada por exemplo em https://github.com/zeit/next.js/issues/4998#issuecomment -464345554, é prefixar href assim (simplificado):

export default ({ children, href, ...rest }) => (
  <Link href={`${process.env.ASSET_PREFIX}${href}`} {...rest}>
    {children}
  </Link>
);

Conforme relatado por outros nesta discussão, isso quebra prefetching como os pedidos são subitamente para / subdir /_next/static/.../pages/ subdir /example.js - o outro "subdir" não deveria estar lá. Mas com nosso componente Link , estamos definindo href como /subdir/example , então não é de se admirar que Next.js esteja solicitando um pacote da página pages/subdir/example.js .

Ent√£o, OK, a pr√©-busca problem√°tica n√£o parece o fim do mundo (embora a UX seja muito feia), mas em nosso aplicativo, as coisas pioram √† medida que usamos o roteamento din√Ęmico do Next.js 9. Para isso, precisamos definir as corretamente para que a evolu√ß√£o do componente Link assim:

export default ({ children, href, as, ...rest }) => (
  <Link 
    href={`${process.env.ASSET_PREFIX}${href}`}
    as={`${process.env.ASSET_PREFIX}${as}`}
    {...rest}
  >
    {children}
  </Link>
);

O uso é:

<CustomLink href='/post/[id]' as='/post/1'>...</CustomLink>

que é convertido em:

<Link href='/subdir/post/[id]' as='/subdir/post/1'>...</Link>

e isso não funcionou para mim quando implantado no Now - tentar navegar para https://deployment-id.now.sh/subdir/post/1 levou a 404. Não tenho certeza do motivo, talvez seja também um problema com o construtor @now/next ( ATUALIZAÇÃO : é por causa de https://github.com/zeit/next.js/pull/8426#issuecomment-522801831) mas, no final das contas, estamos confundindo o roteador Next.js quando pedimos /subdir/post/[id] componente quando esse arquivo não existe no disco.

Há outro exemplo neste tópico, https://github.com/zeit/next.js/issues/4998#issuecomment -521189412, que prefixa apenas como , não href, assim (simplificado):

export default ({ children, href, as, ...rest }) => (
  <Link href={href} as={`${process.env.ASSET_PREFIX}${as}`} {...rest}>
    {children}
  </Link>
);

mas isso gerar√° este erro no navegador:

Seu <Link> as é incompatível com o href . Isso é inválido.

√Č um problema relatado em https://github.com/zeit/next.js/issues/7488.

Depois de tudo isso, não acho que haja uma solução até que algo como basePath seja suportado, o que terei prazer em ajudar.

@borekb Tamb√©m estou pronto para ajudar, como mencionei algumas vezes antes. Todas as solu√ß√Ķes alternativas que vi at√© agora resolvem apenas parte do problema. No momento, estamos usando um fork do next.js na produ√ß√£o, que implementa o basePath.

Em breve apresentaremos uma nova API que tornar√° esta proposta obsoleta.

@tim Ainda é o caso ou a nova proposta de API foi encerrada? https://github.com/zeit/next.js/issues/7329

Btw. amanh√£ far√° exatamente um ano abri esta edi√ß√£o ūüéČ

Uma ideia relativamente selvagem é ter páginas em algo como src/pages e, em seguida, vinculá-las simbolicamente ao local apropriado. Por exemplo:

  • Para implantar em myapp.example.com , eu vincularia src/pages a pages
  • Para implantar em example.com/myapp , eu vincularia src/pages a pages/myapp

Em combina√ß√£o com o componente <Link> e assetPrefix , _poderia_ funcionar, mas n√£o tenho coragem de experiment√°-lo ūüėĄ.

Alguma atualização com isso?

Algum progresso no suporte de basePath ? :)

@nicholasbraun

Agora, em cada clique de link ou evento de envio de roteador, a p√°gina recarrega frowning_face

Tive esse problema, mas resolvi usar o par√Ęmetro 'as' no link, ent√£o o link aponta para o arquivo interno, mas o 'as' √© relativo ao caminho
por exemplo:
<Link href={"/${item.link}"} as={"./${item.link}"}>

Você salvou meu dia! :)))

estou fazendo o mesmo com Router.push(`/route`, `${process.env.BASE_PATH}route`);

@nicholasbraun

Agora, a cada clique de link ou evento de envio de roteador, a p√°gina √© recarregada ‚ėĻÔłŹ

Tive esse problema, mas resolvi usar o par√Ęmetro 'as' no link, ent√£o o link aponta para o arquivo interno, mas o 'as' √© relativo ao caminho
por exemplo:
<Link href={"/${item.link}"} as={"./${item.link}"}>

Esta solução não funciona com o próximo roteamento baseado em 9 arquivos. /route/[id] , ${process.env.BASE_PATH}/route${id} gera este erro

Este coment√°rio explica o problema muito bem.

Embora eu tenha visto algumas pessoas discutindo como as solu√ß√Ķes aqui quebram a pr√©-busca. Para n√≥s, h√° outra quest√£o mais importante.

Com next9, usar um assetPrefix em seu href faz next _sempre_ executar uma rota de servidor. Eu criei um repositório de reprodução nesta edição que demonstra o que está acontecendo.

Isso basicamente quebra o cache do cliente Apollo, pois ele é recriado em todas as rotas.

Acho que a implementação está comparando a página subjacente href sem um assetPrefix com as próximas rotas href (que inclui um assetPrefix) - resultando em uma rota profunda.

por exemplo, se você estiver em href /prefix/page (a página subjacente é apenas /page ) e sua próxima rota href é /prefix/page/[id] (porque sem o prefixo será 404) esta é uma rota completamente diferente e uma rota rasa não é possível.

Procurando solu√ß√Ķes imediatas com rotas expressas

Quando usar componente com os href props que é basePath, a pré-busca não está funcionando.
PLZ suporta basePath e pré-busca, será incrível

Eu poderia realmente usar isso. Estou executando v√°rios aplicativos de uma √ļnica fonte de servidor e cada um separado em seu pr√≥prio web/appX/{next project files} . Seria √≥timo ter mais controle sobre o basePath. Eu descobri uma solu√ß√£o alternativa por enquanto, mas n√£o √© muito bonito.

a exporta√ß√£o est√°tica tamb√©m precisa de basePath ūüėä

parece sucesso no trabalho ūüĎŹ

{
  experimental:{
    basePath: '/some/dir',
  }
}

Esta é uma limitação muito ruim para nós, infelizmente :(

Temos todos os aplicativos atrás de um proxy reverso, portanto, os caminhos precisam ser prefixados (no exemplo abaixo, é o prefixo de /auction-results )

J√° usamos o prefixo assetPrefix - e isso permite que os aplicativos sejam executados corretamente para solicita√ß√Ķes do servidor.
Por exemplo: mydomain.com/auction-results/ funciona bem usando algum roteamento expresso como:

router.get(`/${appPrefix}/`, (req, res) => {
  nextApp.render(req, res, '/national', req.params);
});

Mas quando tentamos fazer a navegação do lado do cliente via next/link , por exemplo:

Onde /auction-results é o prefixo do aplicativo e /national é a página em ~pages/national

<Link href="/national" as="/auction-results/">
  <a>Goto National Page</a>
</Link>

Isso n√£o faz nada (clique fantasma)

Ter links de atualização de página inteira não é o ideal.

Se houver alguma maneira de eu poder ajudar com isso, eu adoraria

Qualquer atualiza√ß√£o sobre isso ... no ano passado, nessa √©poca, me deparei com esse problema. Agora, um ano depois, estou trabalhando em um novo aplicativo e tenho que fazer as mesmas solu√ß√Ķes alternativas que fiz no ano passado ... um pouco alarmante para uma rea√ß√£o "pronta para produ√ß√£o". Os caminhos de base devem ser uma caracter√≠stica comum.

Qualquer atualiza√ß√£o sobre isso ... no ano passado, nessa √©poca, me deparei com esse problema. Agora, um ano depois, estou trabalhando em um novo aplicativo e tenho que fazer as mesmas solu√ß√Ķes alternativas que fiz no ano passado ... um pouco alarmante para uma rea√ß√£o "pronta para produ√ß√£o". Os caminhos de base devem ser uma caracter√≠stica comum.

Não tenho certeza do que você espera ao postar isso.

Next.js est√° sendo trabalhado em tempo integral pela minha equipe (5 pessoas), e estamos trabalhando em muitos recursos ao mesmo tempo. No ano passado, trabalhamos nisso:

Tornando eficazmente os aplicativos Next.js (novos e existentes) significativamente menores, mais r√°pidos e mais escal√°veis.

Se voc√™ quiser expressar seu "voto positivo" para um recurso, pode. use o recurso ūüĎć no thread inicial.

Eu definitivamente concordo que basePath deve ser um recurso integrado. Já está no roteiro e eu até escrevi um PR inicial, que você poderia ter visto lendo o tópico.

Aqui est√° o PR: https://github.com/zeit/next.js/pull/9872

Sinta-se √† vontade para entrar em contato com [email protected] se desejar contribuir financeiramente para que esse recurso aconte√ßa.

Qual é o status disso? estamos realmente dependendo disso: /

O suporte do

cf. # 9872

@martpie eu j√° vi, mas para. meu caso basePath n√£o √© apenas um, pode ser v√°rios basePath, uma vez que servimos nosso aplicativo por meio de diferentes "URLs" e configurar basePath durante o tempo de compila√ß√£o n√£o √© uma op√ß√£o (mesmo que tenha para suportar uma s√©rie de caminhos em vez de uma √ļnica string)

@timneutkens Obrigado pela atualização. Você faria a gentileza de dar outra atualização. Isso é para nós uma característica fundamental e precisamos saber ...

  1. Será esta apenas uma empresa (sua referência para entrar em contato com o departamento de vendas da empresa causou alguma irritação)?

  2. Parece que está no roadmap, de acordo com o PR não será removido novamente; você pode dar alguma indicação se é seguro construir em torno deste recurso agora sem nenhuma surpresa nos próximos meses, como uma versão de código aberto inválida e outra com suporte total depois de negociarmos semanas com alguns vendedores aleatórios sobre preços arbitrários?

Eu entendo que voc√™s trabalham em muitos recursos e todos t√™m suas prioridades, mas configura√ß√Ķes ainda menores precisam de proxy. Em seguida, execute v√°rias inst√Ęncias e d√™ a ele basePath por servi√ßo dedicado. Antes de come√ßarmos a construir v√°rios servi√ßos no Next, precisamos saber qu√£o prov√°vel e em breve esse recurso estar√° dispon√≠vel como c√≥digo aberto completo. Caso contr√°rio, seria muito arriscado investir mais tempo no Next.

Agradecemos sua compreens√£o e aguardamos seus coment√°rios.

FWIW, agora estou funcionando e para outros que est√£o dirigindo por:

Coloque isso em seu next.config.js :

module.exports = {
  experimental: {
    basePath: '/custom',
  },
}

Ent√£o, eu precisei reiniciar o servidor e configurar o middleware do meu servidor da web corretamente:

Pego todas as solicita√ß√Ķes por meio de um caminho personalizado, por exemplo. app.use('/custom', (req, res...) => { ... e ent√£o (o que era importante) eu preciso proxy para a URL do sistema onde o Next est√° rodando (ent√£o o endere√ßo interno de sua orquestra√ß√£o de cont√™iner e novamente com o respectivo caminho se voc√™ usar http-proxy => por exemplo. ... target: 'http://next:3000/custom ), n√£o apenas o host sem o caminho personalizado. Se voc√™ usar http-proxy-middleware voc√™ n√£o precisa disso.

Parece muito bom, espero que este recurso não precise de nenhuma licença EE. Se sua equipe precisar de ajuda para amadurecer esse recurso, por favor, nos avise, talvez possamos ajudar!

Edit: Tentei isso também no modo de produção do Next e parece funcionar bem.

@timneutkens Obrigado pela atualização. Você faria a gentileza de dar outra atualização. Isso é para nós uma característica fundamental e precisamos saber ...

  1. Será esta apenas uma empresa (sua referência para entrar em contato com o departamento de vendas da empresa causou alguma irritação)?
  2. Parece que está no roadmap, de acordo com o PR não será removido novamente; você pode dar alguma indicação se é seguro construir em torno deste recurso agora sem nenhuma surpresa nos próximos meses, como uma versão de código aberto inválida e outra com suporte total depois de negociarmos semanas com alguns vendedores aleatórios sobre preços arbitrários?

Eu entendo que voc√™s trabalham em muitos recursos e todos t√™m suas prioridades, mas configura√ß√Ķes ainda menores precisam de proxy. Em seguida, execute v√°rias inst√Ęncias e d√™ a ele basePath por servi√ßo dedicado. Antes de come√ßarmos a construir v√°rios servi√ßos no Next, precisamos saber qu√£o prov√°vel e em breve esse recurso estar√° dispon√≠vel como c√≥digo aberto completo. Caso contr√°rio, seria muito arriscado investir mais tempo no Next.

Agradecemos sua compreens√£o e aguardamos seus coment√°rios.

@ pe-s Acho que você está entendendo mal a minha postagem.

N√£o existe uma "vers√£o Enterprise Next.js" no momento. Eu estava me referindo √†s in√ļmeras ocasi√Ķes em que empresas externas procuraram pagar por consultoria para desenvolver recursos como este em um per√≠odo mais curto. Por exemplo, o suporte de zonas foi criado em colabora√ß√£o com a Trulia.

Este recurso ainda est√° sendo trabalhado e est√° no roteiro. Todos os recursos que est√£o sendo trabalhados s√£o de c√≥digo aberto, como eu disse, n√£o h√° vers√£o corporativa do Next.js. Temos v√°rias prioridades de trabalho de alto impacto no roteiro, embora seja por isso que me referi a entrar em contato com [email protected] se voc√™ precisar desse recurso o mais r√°pido poss√≠vel / para discutir o suporte corporativo para Next.js.

@timneutkens tx pela sua resposta r√°pida e excelente! Ent√£o, podemos ir all in :)
Continue com o ótimo trabalho!

O suporte do Basepath está disponível em next@canary agora, não é mais experimental. Estará no canal estável em breve.

Estou muito atrasado para isso, mas você considerou usar HTML real

O suporte do Basepath está disponível em next@canary agora, não é mais experimental. Estará no canal estável em breve.

@timneutkens , obrigado por esta adição. Você sabe quando o suporte basePath não experimental será lançado oficialmente?

Al√©m disso, quando eu defino o basePath, os ativos (localizados na pasta p√ļblica) s√£o servidos no url apropriado, conforme o esperado. Mas, quando fa√ßo refer√™ncia a eles em meu c√≥digo, tenho que adicionar o caminho base ao src manualmente, porque caso contr√°rio, eles ainda ser√£o referenciados a partir do caminho normal. Este √© o uso esperado de basePath? Eu tamb√©m tentei usar o assetPrefix, mas n√£o teve nenhum efeito no meu c√≥digo que eu pudesse dizer.

Exemplo :

  1. usando next v9.4.5-canary.24
  2. basePath definido como /alerts em next.config.js:
const basePath = '/alerts';
module.exports = {
  basePath: basePath,
  env: {
    BASE_PATH: basePath,
  },
};
  1. ativo localizado em public/images/example.png
  2. exemplo de uso de ativo no componente de reação:
const ExampleImage = () => (
  <img src={`${process.env.BASE_PATH}/images/example.png`} />
);

Em meus testes, n√£o estou atualizando os URLs dos ativos.

Instalei o can√°rio mais recente:
npm install [email protected]

next.config.js

const isProd = process.env.NODE_ENV === 'production';

module.exports = {
  basePath: isProd ? '/example' : ''
}

Todas as p√°ginas e links carregam corretamente:
http: // localhost : 3000 / example / posts / pré-renderização
http: // localhost : 3000 / example / posts / ssg-ssr
http: // localhost : 3000 / example / posts / pré-renderização

Mas imagens, favicons etc. n√£o s√£o mapeados:
http: // localhost : 3000 / favicon.ico 404
http: // localhost : 3000 / images / profile.jpg 404

Alguém testou isso? Também tentei usar o assetPrefix, mas também não funcionou.

Além disso, estou confuso, por que não usar a funcionalidade do navegador embutido para isso?
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

Obrigado por analisar isso também, @kmturley . Fico feliz em saber que não sou só eu.
@timneutkens , devemos reabrir este problema / criar um novo problema para este bug?

Você tem que prefixar as imagens manualmente. Você pode obter o basePath usando

const {basePath} = useRouter()

https://nextjs.org/docs/api-reference/next.config.js/cdn-support-with-asset-prefix

Next.js usar√° automaticamente seu prefixo nos scripts que carrega, mas isso n√£o tem nenhum efeito na pasta p√ļblica;

Agora, eu percebi que existem v√°rias maneiras de vincular arquivos em / public. por exemplo, <img/> <link/> ...
√Č por isso que temos que especificar manualmente o basePath para cada um?

Se houvesse um componente como o abaixo dispon√≠vel, acho que economizaria tempo e reduziria as confus√Ķes de muita gente?

<WithinBasePath>
  {/* automatically fixes the path with basePath */}
  <img src="/logo.png" />
</WithinBasePath>

Eu realmente não acho que isso seja apropriado, mas é isso que eu quis dizer.

// src/components/WithinBasePath/index.tsx

import React from "react"
import path from "path"
import { useRouter } from "next/router"
interface Props {}

const WithinBasePath: React.FC<Props> = (props) => {
  const { basePath } = useRouter()
  const children = [props.children].flatMap((c) => c) as React.ReactElement[]
  return (
    <>
      {children.map((child, key) => {
        let newChild = null

        switch (child.type) {
          case "img":
            newChild = React.createElement(child.type, {
              ...child.props,
              src: path.join(basePath, child.props.src),
              key,
            })
            break
          case "link":
            newChild = React.createElement(child.type, {
              ...child.props,
              href: path.join(basePath, child.props.href),
              key,
            })
            break
          default:
            newChild = React.createElement(child.type, {
              ...child.props,
              key,
            })
        }
        return newChild
      })}
    </>
  )
}
export default WithinBasePath

// pages/test.tsx

import React from "react"
import WithinBasePath from "@src/components/WithinBasePath"
interface Props {}

const test: React.FC<Props> = (props) => {
  return (
    <WithinBasePath>
      <img src="/123.jpg" />
      <link href="/abc.jpg" />
      <div>other element</div>
    </WithinBasePath>
  )
}
export default test

Para aqueles que estão tentando usar const {basePath} = useRouter() que é um Gancho, para trabalhar com Classes e Componentes e obtendo este erro:

Aviso de chamada de gancho inv√°lido

https://reactjs.org/warnings/invalid-hook-call-warning.html

Você pode fazê-lo funcionar usando:

import { withRouter, Router } from 'next/router'

class Example extends Component<{router: Router}, {router: Router}> {
  constructor(props) {
    super(props)
    this.state = {
      router: props.router
    }
  }
  render() {
    return (
      <Layout home>
        <Head><title>Example title</title></Head>
        <img src={`${this.state.router.basePath}/images/creators.jpg`} />
      </Layout>
    )
  }
}
export default withRouter(Example)

Se você quiser usar basePath com markdown, parece que você precisa fazer um localizar e substituir na string:

const content = this.state.doc.content.replace('/docs', `${this.state.router.basePath}/docs`);
return (
<Layout>
  <Container docs={this.state.allDocs}>
    <h1>{this.state.doc.title}</h1>
    <div
      className={markdownStyles['markdown']}
      dangerouslySetInnerHTML={{ __html: content }}
    />
  </Container>
</Layout>
)

Você tem que prefixar as imagens manualmente. Você pode obter o basePath usando

const {basePath} = useRouter()

Esta solução não leva em consideração imagens importadas em um arquivo css ou scss. Você tem uma solução sobre como definir o caminho base ao importar um ativo de um arquivo css ou scss?
Com esta solução, teremos que garantir que todas as imagens sejam importadas por meio de uma tag img, estilo inline ou na tag de estilo. Não é o ideal, porque dividirá seus estilos para serem implementados em vários lugares.

@peetjvv Aqui est√° uma solu√ß√£o <CSSVariables> em _app.tsx , que injeta um elemento <style> global embutido contendo vari√°veis ‚Äč‚ÄčCSS, que voc√™ pode usar em todas as suas folhas de estilo.

Por exemplo, na abertura de <body> vari√°veis ‚Äč‚Äčde constru√ß√£o e inje√ß√£o:

<style>
:root {
      --asset-url: url("${basePath}/img/asset.png");
}
</style>

Para obter esse basePath, uso a abordagem de @kmturley usando withRouter .
Veja como esse componente poderia ser:

import { withRouter, Router } from "next/router";
import { Component } from "react";

export interface IProps {
  router: Router;
}

class CSSVariables extends Component<IProps> {
  render() {
    const basePath = this.props.router.basePath;
    const prefixedPath = (path) => `${basePath}${path}`;
    const cssString = (value) => `\"${value}\"`;
    const cssURL = (value) => `url(${value})`;
    const cssVariable = (key, value) => `--${key}: ${value};`;
    const cssVariables = (variables) => Object.entries(variables)
      .map((entry) => cssVariable(entry[0], entry[1]))
      .join("\n");
    const cssRootVariables = (variables) => `:root {
      ${cssVariables(variables)}
    }`;

    const variables = {
      "asset-url": cssURL(
        cssString(prefixedPath("/img/asset.png"))
      ),
    };

    return (
      <style
        dangerouslySetInnerHTML={{
          __html: cssRootVariables(variables),
        }}
      />
    );
  }
}

export default withRouter(CSSVariables);
Esta p√°gina foi √ļtil?
0 / 5 - 0 avalia√ß√Ķes

Quest√Ķes relacionadas

swrdfish picture swrdfish  ¬∑  3Coment√°rios

jesselee34 picture jesselee34  ¬∑  3Coment√°rios

DvirSh picture DvirSh  ¬∑  3Coment√°rios

irrigator picture irrigator  ¬∑  3Coment√°rios

formula349 picture formula349  ¬∑  3Coment√°rios