Next.js: Chamada de gancho inválida em 9.0.6

Criado em 10 out. 2019  ·  74Comentários  ·  Fonte: vercel/next.js

Relatório de erro

Descreva o bug

Quando você usa o react, um componente que reside fora da pasta principal do projeto Next.js, que usa ganchos. Você acaba recebendo Invalid hook call erro e o aplicativo quebra. Componentes sem ganchos funcionam conforme o esperado.

O bug aparece em todas as versões >9.0.5 quando você muda a configuração do webpack para que os arquivos fora da pasta principal sejam transpilados. Está funcionando bem em <=9.0.5

Reproduzir

Confira a reprodução em https://github.com/baldurh/next-9.0.6-bug-repro

Comportamento esperado

O código não deve quebrar ao usar arquivos fora da pasta do projeto.

Informação do sistema

  • SO: N / A
  • Navegador: N / A
  • Versão do Next.js: >=9.0.6

Contexto adicional

Eu sei que provavelmente não é um uso comum de Next.js, mas em nosso projeto estamos usando um monorepo e temos uma pasta compartilhada com componentes usados ​​por vários aplicativos. Seria bom fazer isso funcionar novamente. Se alguém encontrar uma configuração alternativa que possamos usar, também ficarei feliz em fazer isso 🙂

story 3 needs investigation

Comentários muito úteis

Olá, alguma atualização sobre este problema? Temos um monorepo e estamos encontrando exatamente esse problema.

Todos 74 comentários

@baldurh Isso é realmente muito incomum, ao usar plataformas como Agora, apenas a pasta onde o aplicativo Next.js reside é implantada, é melhor assim, porque caso contrário, você precisaria saber sobre todos os módulos externos primeiro. 2 alternativas melhores são:

  • Mova tudo para um único aplicativo Next.js
  • Use pacotes npm privados ou lerna ou similar

@lfades obrigado pela resposta. Nenhuma dessas opções está disponível para nós e não estamos implantando no Now ou algo semelhante. Usamos espaços de trabalho de yarn inicialmente, mas depois integramos o bazel e ele não combina bem com a natureza de links simbólicos dos espaços de trabalho de yarn. Pacotes Npm significa que não podemos desenvolver os módulos compartilhados tão rápido quanto gostaríamos. É muita sobrecarga.

@baldurh Acabei de encontrar isso com next-i18next, pois temos aplicativos NextJs aninhados como exemplos. Você encontrou uma solução alternativa?

@isaachinman Não temos. Não conseguimos atualizar para o 9.x ainda por outros motivos, então não estou investigando. Alguém tem uma ideia de onde pode estar o código que afeta isso? Adoraria compreender melhor o problema.

Ainda não tive tempo de me aprofundar nisso, mas se alguém precisar de uma reprodução: clone next-i18next , cd em examples/simple e atualize a versão NextJs para> = 9.0.6.

Está atualmente no 9.0.3, então esta é tecnicamente uma alteração importante em um patch.

Eu tive um erro semelhante recentemente e tive que fazer o downgrade para 9.0.5 (e React 16.8.x). Eu meio que reduzi o problema que vi ao uso de MDX da Next, mas não tenho nenhum detalhe concreto além disso.

Eu pesquisei o mesmo problema com um grande projeto baseado no Next & next-i18next.

Vi que esse erro pode ser causado por 3 motivos:

  1. Versões de reação e reação desalinhadas - não se aplica ao meu aplicativo
  2. 2 versões do react-dom importadas - não se aplica ao meu aplicativo
  3. Uso impróprio de ganchos React - eu não uso ganchos, mas algumas bibliotecas são, e parece que funciona para todos os outros.

O estranho é que isso acontece apenas na construção de produção.

@timneutkens @Timer, desculpe por receber sua opinião . Você acha que isso é algo que poderia ser corrigido? Todos nós precisamos implementar algumas soluções alternativas? Este é um grande bloqueador para nós no momento. Obrigado.

Parece que você aliasou react mas não react-dom . Você pode tentar isso?

Obrigado @Timer . Tentei mas não surtiu efeito

Consegui resolver isso agora mesmo na reprodução , movendo as dependências react e react-dom um nível acima. Eu apenas empurrei as mudanças se alguém quiser experimentar. Não tentei em nosso projeto real, mas tenho esperança de que funcione para nós. Talvez isso possa resolver o problema de @isaachinman , @jaredcwhite e @felixmosh também?

@Timer Eu tenho esta trabalhando em nosso projeto, mas eu também tinha que ter certeza que eu não tinha outras dependências que instalaram react para os nossos projectos node_modules pasta. No nosso caso, foi relacionado ao livro de histórias ( yarn why react ajudou muito 😄). Estávamos planejando mover o livro de histórias para um projeto separado, então acho que essa solução funcionará em nosso caso.

Ah sim. Pacotes node_module publicados inadequadamente causarão isso (com dependências em react(-dom|) invés de dependência de pares).

Consegui resolver isso agora mesmo na reprodução , movendo as dependências react e react-dom um nível acima. Eu apenas empurrei as mudanças se alguém quiser experimentar. Não tentei em nosso projeto real, mas tenho esperança de que funcione para nós. Talvez isso possa resolver o problema de @isaachinman , @jaredcwhite e @felixmosh também?

Você pode explicar as mudanças que você fez neste repo?

Eu corro npm ls react ou npm ls react-dom Eu tenho apenas meu próximo aplicativo na lista.

@felixmosh Desculpe, aparentemente o push falhou para mim ontem. Agora as mudanças estão definitivamente lá 😅 Mudei react e react-dom da pasta app para a pasta raiz, então agora você precisa fazer yarn/npm install em ambos os app pasta e a pasta raiz antes de executar o app . Espero que esteja claro o suficiente.

Teremos que fazer algumas mudanças em nosso sistema de compilação para fazê-lo funcionar em produção, então esta solução ainda é um pouco incômoda para nós 😝

Obrigado pela explicação, vou esperar a próxima equipe resolver isso, parece um pouco estranho colocar o react deps na raiz do meu mono-repo ...

@felixmosh Sim, meio que concordo com você. No entanto, se você usar algo como espaços de trabalho de fios, é exatamente isso que essa ferramenta fará. Se você tiver a mesma dependência em dois ou mais projetos, isso irá içar as dependências para a raiz. É bom porque garante que você tenha a mesma versão das dependências em todos os seus projetos. Mas se você não tem uma ferramenta como essa, você mesmo terá que gerenciá-la, o que é um pouco estranho. Concordo que a melhor solução seria que a equipe Next.js desse uma olhada e resolvesse isso para todos nós 😇🙏🏻

Encontrar o mesmo problema, elevar react e react-dom um nível e executar o servidor a partir da raiz é a única solução alternativa que funciona atualmente no 9.1.5. Vinculando https://github.com/facebook/react/issues/13991 e https://github.com/facebook/react/issues/15315#issuecomment -479802153 para referência, pois encontrei esses links antes desta edição.

Olá, alguma atualização sobre este problema? Temos um monorepo e estamos encontrando exatamente esse problema.

Encontro com o mesmo problema.
A v9.0.5 funciona muito bem com ganchos para componentes importados fora de rootFolder.

A partir de 9.0.6 até 9.1.6-canary.5 têm os mesmos problemas.

O problema ocorre apenas no lado do servidor. Se o SSR estiver desabilitado (por exemplo, carregar componente externo via dinâmica ), tudo funcionará conforme o esperado para as versões> = 9.0.6.

@nodkz é um problema com a resolução do pacote

@Timer este problema foi movido para o "próximo" marco em cerca de 6 versões, ele me impede de atualizar para a versão mais recente.

Perdi um dia inteiro de tempo em acomodações com isso, não sei qual é a origem do problema, até tentei a solução alternativa (que não funcionou).

Você precisa de ajuda para investigar qualquer direção?
Você tem algum pressentimento sobre isso?
Por que isso acontece apenas na construção de produção?
O que foi alterado de 9.0.5 para 9.0.6 que pode estar relacionado a isso?

Thanx 🙏🏼

Acho que encontrei o problema !!!
Acho que é uma combinação de 2 coisas:

  1. uso de sym-link para node_modules
  2. i18next / react-i18next não eram externos nos pacotes do servidor !!
    image
    No meu caso, quando ele explode no build de produção, ele reclama no i18next useTranslation hook ...

Então, eu investiguei o motivo pelo qual existem módulos de nó dentro de pacotes de servidores (a prática recomendada para pacotes de servidores é torná-los externos).

Eu vi que o próximo tem algumas exceções para a próxima lib (por quê?), A parte engraçada é que esta regex captura todas as libs que terminam com next/dist/ , como i18next & react-i18next !!

Então, se você mudar isso:

res.match(/next[/\\]dist[/\\]/) 

para dentro

res.match(/[/\\]next[/\\]dist[/\\]/) 

O pacote do servidor excluirá todas as libs que não sejam next e terminem com next/dist e resolveu o problema!

Para mim, o principal problema é a nova maneira como as solicitações são resolvidas: https://github.com/zeit/next.js/blob/canary/packages/next/build/webpack-config.ts#L446

Como temos componentes fora da raiz do projeto, a resolução da solicitação gerará um erro que resultará em react sendo agrupado nos blocos do servidor. E é por isso que obtemos o erro Invalid hook call no servidor.

@baldurh context nessa expressão que você vinculou é fornecida por webpack e é diferente da raiz de compilação (seu diretório de projeto).
É sempre o diretório do arquivo que está emitindo o requerimento.

Direito. Eu corrigi isso para que funcione para nós por enquanto. Acho que eventualmente mudaremos a estrutura do código para que as dependências sejam compartilhadas em um nível de diretório superior. No entanto, mesmo se react estiver disponível na pasta externa (fora da raiz), ainda recebo o erro.

Estou tentando usar um pacote vinculado e estou tendo o mesmo problema. Infelizmente, nenhuma das correções de https://github.com/facebook/react/issues/13991 funcionou 🙁

Também estou tendo o mesmo problema com uma biblioteca de componentes com link simbólico yarn link . Isso funcionou bem até v9.0.6-canary.4 e agora estou na mesma posição que alguns outros comentaristas e não posso atualizar depois disso. Eu apontei a mudança para este PR https://github.com/zeit /next.js/pull/8739

Minha biblioteca de componentes usa react , react-dom e styled-components . A configuração para isso é a seguinte

  • Adicionados os pacotes como devDependencies e incluídos em peerDependencies
  • Adicionados os pacotes como externos na configuração do meu webpack
  • Adicionados aliases de resolução a esses pacotes na minha próxima configuração
  • Transpilou o módulo da biblioteca de componentes com next-transpile-modules

Atualizar

Consegui corrigir isso incluindo esses módulos nas partes externas do servidor. Agradecimentos a @HosseinAgha neste comentário https://github.com/martpie/next-transpile-modules/issues/50#issuecomment -558318688

if (isServer) {
  config.externals = [
    'react',
    'react-dom',
    'styled-components',
    ...config.externals
  ]
}

Estou vendo exatamente os mesmos problemas, nenhuma das soluções alternativas funcionou para mim até agora.

Meu pacote funciona se eu publicá-lo e instalá-lo (e usar resolve.alias em meu next.config.js).

Mas rodar um dev build com o pacote vinculado via yarn link @mypackage sempre resulta em um erro de gancho inválido.

Também consegui fazê-lo funcionar modificando node_modules/dist/build/wepack-config.js e comentando as linhas adicionadas em https://github.com/zeit/next.js/pull/8739

O que vejo se logar baseRes e res é que a condição if é acionada como:

  • /myApp/node_modules/react/index.js! == /myApp/node_modules/myPackage/node_modules/react/index.js
  • do meu entendimento, isso dispara se o caminho não for o mesmo, mesmo o arquivo / versão é 100% idêntico

Atualizar:

Conseguimos contornar o problema convertendo nosso pacote para usar espaços de trabalho yarn (embora nosso repositório contenha apenas um único pacote).
Mudamos nosso código de ./src para ./package/our-package-name/src e configuramos yarn workspaces => https://classic.yarnpkg.com/en/docs/workspaces/

Isso contorna o problema, pois vai elevar as dependências comuns para a pasta ./node_modules de nível superior e ./package/our-package-name/node_modules permanecerá praticamente vazio.

Portanto, agora, quando vincularmos nosso próximo pacote, não obteremos mais uma segunda versão do react (já que ele não está presente em nossa pasta de pacotes node_modules) e tudo funciona como deveria.

Eu tenho a porra do mesmo problema. ¬¬ '

Geralmente desistimos dos palavrões, pois isso é contra o código de conduta.

Desculpe, eu estava com raiva desse bug. Na verdade, gosto muito do Next.JS. Mas não posso usar porque esse assunto é chato.

Estamos enfrentando esse problema ao trabalhar com pacotes locais externos e next-transpile-modules .

Como queremos continuar com a versão mais recente do Next.js, tentarei enviar um patch para o Next.js se encontrar a causa raiz.

Eu enfrento o mesmo problema, após instalar [email protected]
Minhas dependências são [email protected] , [email protected] , [email protected] e, claro, muitas outras libs (mas tudo estava funcionando antes de instalar o next-i18next). Se alguém tiver uma solução alternativa, pode ser ótimo: +1:

Obrigado por postar este problema, eu também tive problemas com o symlinking do nosso pacote de sistema de design (biblioteca de componentes react). Também estamos transpilando usando https://github.com/martpie/next-transpile-modules.

A correção sugerida aqui funcionou para nós:

  • Crie um link simbólico para sua biblioteca em sua pasta node_modules (fizemos isso com nosso próprio utilitário em vez de npm link mas deve ser basicamente o mesmo)
  • Adicione algo como o seguinte ao seu next.config.js :
// next.config.js
const nextConfig = {
    webpack: (config, options) => {
        // modify the `config` here

        if (options.isServer) {
            config.externals = ["react", ...config.externals];
        }
        config.resolve.alias["react"] = path.resolve(__dirname, ".\\node_modules\\react");

        return config;
    },
};
// more plugins etc...

Nossa solução alternativa que não requer configuração

  • Link simbólico de tudo, exceto node_modules do seu pacote. Criei meu próprio utilitário para isso talvez possa postá-lo no github.

Mas seria bom ver isso corrigido no NextJS, passei muito tempo tentando entender por que o alias do webpack funcionava para todos os meus projetos não NextJS :)

PS. Não tenho ideia de como isso afetaria uma construção de produção, mas só usaríamos isso durante o desenvolvimento

if (options.isServer) {
            config.externals = ["react", ...config.externals];
        }

react já está no lado do servidor externo.

config.resolve.alias["react"] = path.resolve(__dirname, ".\\node_modules\\react");

Isso não resolverá o problema.

Como dito antes, este problema está relacionado às suas dependências dependendo de react enquanto eles deveriam ter peerDependency em react (e reação, se necessário).

@timneutkens

Bem, não, nem sempre é o caso. Eu com certeza tenho react e react-dom como dependências de peer. O problema ainda ocorre se você, por exemplo, criar um link simbólico de sua biblioteca para um projeto nextjs. O que acontece então é que você terá uma pasta node_modules dentro da sua biblioteca (pelo menos se você já executou npm i ou npm link nessa pasta da biblioteca).

Quando o react for resolvido a partir desta pasta de biblioteca, ele será resolvido para o que está nessa pasta node_modules e você obterá cópias duplas do react que está causando o problema. Se eu deletar a pasta node_modules dentro de minha biblioteca ou instalá-la usando algo diferente de npm link então sim, ofc, funciona (se você usar dependências de mesmo nível ou exatamente a mesma versão de reação).

Então, para resolver isso durante o desenvolvimento, você deve ser capaz de usar um apelido para reagir para forçar todos a usar a mesma versão. Por causa dos problemas mencionados aqui, isso não tem efeito na versão atual do NextJS sem adicionar a parte config.externals ... (pelo menos para mim), provavelmente como as pessoas mencionaram aqui devido a alguma mudança, conforme observado aqui # 8739?

Um problema semelhante está acontecendo comigo, mas (potencialmente) por causa da biblioteca material-ui (conforme descrito em # 10162), minha correção temporária por agora foi apenas adicionar npm run clean em meu preserve e Scripts dev conforme descrito aqui:
https://github.com/zeit/next.js/issues/10162#issuecomment -612501431

@timneutkens Eu entendo que o problema real tem a ver com como essas dependências estão listando seus próprios dep (deps vs peer-dep), mas alguma ideia do que podemos fazer em nosso próprio aplicativo para consertar isso de forma mais permanente?

@ ryan-0 Você tem alguma configuração especial? Ficaria surpreso se o material Ui não lista reagir como um dep de pares? Tipo, você usa uma versão de reação muito antiga ou link simbólico qualquer coisa?

sem configuração especial .. sem ligação simbólica e reação 16.13.1 -> temos alguns outros departamentos que podem estar fazendo com que o problema seja justo, mas pelo menos de acordo com esse repro, parece estar relacionado a material-ui / core (que também usamos):
https://github.com/zeit/next.js/issues/10162

@ ryan-0 existe uma pasta node_modules com react dentro da pasta material-ui?

Também começa a trabalhar depois de executar o npm dedupe?

não, parece que não há uma pasta de nó aninhado, e é por isso que estou confuso sobre como o bug está acontecendo. e nenhum npm dedupe não funcionou :(

Estranhamente, usar resolve.alias não parece afetar os pacotes fora da raiz do projeto.

Este é meu arquivo next.config.js :

const path = require('path')

module.exports = {
  webpack: config => {
    const { alias } = config.resolve || {}
    alias.react$ = path.resolve('node_modules/react')
    alias['react-dom$'] = path.resolve('node_modules/react-dom')

    config.resolve = {
      ...config.resolve,
      alias,
    }

    return config
  }
}

Estou usando yarn link com um pacote local que existe em um monorepo Lerna. Sua node_modules não contém uma cópia de react , mas a raiz monorepo faz. Eu não esperaria que isso fizesse diferença enquanto resolve.alias fosse usado, mas infelizmente não é o caso. Depois de remover a cópia de react da raiz do monorepo, agora estou recebendo um erro Cannot find module 'react' .

Alguém encontrou uma boa solução para isso?

Eu tenho uma próxima biblioteca vinculada que estou usando next-transpile-modules para adicioná-la ao meu projeto de 'consumidor'. Eu adicionei o alias react em meu next.config.json conforme mencionado em seus documentos, mas não foi suficiente. Ainda estou recebendo o erro de dependências duplicadas para React.

Você pode tentar usar relative-deps por @mweststrate

Alguém encontrou uma boa solução para isso?

Eu tenho uma próxima biblioteca vinculada que estou usando next-transpile-modules para adicioná-la ao meu projeto de 'consumidor'. Eu adicionei o alias react em meu next.config.json conforme mencionado em seus documentos, mas não foi suficiente. Ainda estou recebendo o erro de dependências duplicadas para React.

Sim, veja minha postagem acima, você precisa adicionar a parte config.externals na minha amostra, então o alias começa a funcionar novamente

@johot Eu tentei sua solução, mas não funcionou muito bem para mim. Comecei a receber alguns erros estranhos, mas principalmente este: cannot destructure property 'query' of 'Object(...)(...)' as it is null depois de tentar sua solução. O objeto visto como nulo neste caso é useRouter de next/router .

@aleclarson Obrigado pela dica. Vou tentar se não conseguir fazer funcionar com a próxima configuração. Você está usando atualmente?

Se você estiver usando next-transpile-modules e Yarn, a solução é bastante simples: https://github.com/martpie/next-transpile-modules#i -have-trouble-with-duplicated-dependencies-or-the -invalid-hook-call-error-in-react

Se você estiver usando npm , ainda estou procurando por uma solução: c

Ok, então minha solução final foi migrar de yarn link para yalc . Eu tenho uma tarefa gulp que observa as alterações dos arquivos e copia os arquivos para minha pasta dist e, em seguida, envia as alterações para a loja Yalc.

No meu 'consumidor' eu modifiquei tsconfig.json para resolver os caminhos assim:

 "paths": {
      "~/*": ["/src/*"],
      "my-library/*": ["./node_modules/my-library/dist/*"]
    },

e em next.config.js adicionei o seguinte:

 experimental: {
      jsconfigPaths: true, // enables it for both jsconfig.json and tsconfig.json
    }

Então, o próximo pode resolver os caminhos com base em tsconfig.json paths . Mais informações aqui .

Resumindo: combinar yalc + next-transpile-modules melhorou muito minha configuração de desenvolvimento local. Sem dependências duplicadas e erros estranhos. O comportamento de adicionar diretamente o módulo usando yarn add e vincular o módulo a yalc são praticamente os mesmos.

Se você estiver usando uma biblioteca vinculada localmente que depende de styled-components , consulte: https://styled-components.com/docs/faqs#linking -in-an-ssr-scenery

Em server/index.js :

const moduleAlias = require('module-alias');
moduleAlias.addAlias('styled-components', path.join(__dirname, '../node_modules/styled-components'));

Mas, também precisamos adicionar o seguinte em next.config.js :

config.resolve.alias['react'] = path.resolve(__dirname, './node_modules', 'react');
config.resolve.alias['react-dom'] = path.resolve(__dirname, './node_modules', 'react-dom');
config.resolve.alias['prop-types'] = path.resolve(__dirname, './node_modules', 'prop-types');
config.resolve.alias['styled-components'] = path.resolve(__dirname, './node_modules', 'styled-components');

Espero que ajude.


Testado com:

Próximo: 9.3.5
Reagir: 16.13.1
componentes estilizados: 5.1.0

Pessoal, conserto simples, remova sua versão global de react, next e react-dom fazendo:
npm remove -g react next react-dom

Pessoal, conserto simples, remova sua versão global de react, next e react-dom fazendo:

npm remove -g react next react-dom

Estou feliz que funcionou para você, mas duvido que muitas pessoas neste segmento tenham essas dependências instaladas globalmente.

Não só na web!
reagir 16,9
reagente nativo 0,62
Executando no Android
Talvez o menor reprodutor da história?

import React, { Component, useState } from 'react';
import {
  AppRegistry,
} from 'react-native';

function hooker() {
  const [count, setCount] = useState(0)
}

class ClassA extends Component {
  constructor(props) {
    super(props)
    //hooker();  //Invalid hook call Error
  }
  componentDidMount(){
    //hooker();  //Invalid hook call Error
  }
  render() {
    hooker();  //Invalid hook call Error
    return (      
      null   
    );
  }
} 
export default function App(props) {
  //hooker();  //No problem
  return (
    <ClassA/>
  );
};

AppRegistry.registerComponent('default', () => App);

Também enfrentei esse problema e lutei contra ele para usar yarn vez de npm (com o npm não funcionou) e usando https://github.com/vercel/next.js/ questões / 9022 # issuecomment -616169466

Existe alguma solução para isso?

Completamente preso à versão 9.4.4.

Problema acontecendo no HOC para rotas privadas abaixo. Eu também tentei usar withRouter mas o mesmo erro foi lançado no componente empacotado.

import { useRouter } from 'next/router'

function withPrivateRoute(WrappedComponent) {
const router = useRouter();                    //**** ERROR IS THROWN HERE *******
class WPR extends React.Component {
    componentDidMount(){
        console.log('wrappeed', WrappedComponent);
        // const { router } = this.props;
        const intendedRoute = router.pathname;
        // const isAdmin = !!cookies.get('isAdmin');
        // const isAuthenticated = !!cookies.get('username');
        const isAuthenticated = false;
        const isAdmin = false;
        if (!isAuthenticated) {
            router.push({
                pathname: '/login',
                query: { from: intendedRoute },
            });
        }
        if (
            isAuthenticated &&
            router.pathname.includes('admin') &&
            !isAdmin
        ) {
            router.push('/');
        }
    }

    render() {
        return ({ ...props }) => <WrappedComponent {...props} />;
    }
}
return WPR;
 }

  export default withPrivateRoute;

Eu tive o mesmo problema, então tive que voltar ao meu branch anterior (onde presumi que esse problema não existia) e adicionar o arquivo de código mais recente por arquivo e descobri que o problema era

import { useToasts, AppearanceTypes } from 'react-toast-notifications';

export const showToast = (message: string, appearance: AppearanceTypes) => {
    const { addToast } = useToasts();
    addToast(message, {
        appearance,
    });
};

Eu estava usando um serviço de notificação e em cada solicitação, se houver um erro showToast aparece, mas agora com este erro, acho que não vou usar este serviço

Posso confirmar que isso está relacionado ao PR https://github.com/vercel/next.js/pull/8739 por @arcanis
Estamos usando uma configuração monorepo com Rush e pnpm, o que elimina o motivo da fusão do PR mencionado. Também significa que o ponto que @timneutkens feito em https://github.com/vercel/next.js/issues/9022#issuecomment -610255555 não se aplica a nós, temos a seguinte estrutura:

website
  dependencies: next, react, react-dom, library
library
  devDependencies: react, react-dom (for tests)
  peerDependencies: react, react-dom

Os library.devDependencies.(react|react-dom) são links simbólicos que apontam para os mesmos arquivos que website.dependencies(react|react-dom) . No entanto, parece que [email protected] que é usado no https://github.com/vercel/next.js/blob/f98e38c9b634b85e6679e7b5f953a9d98074cfc3/packages/next/lib/resolve-request.ts#L16 não segue o atual comportamento padrão do Node.js preservando os links simbólicos.

Acabamos com o seguinte:

  1. Configurando os next-transpile-modules para transpilar nosso código em library
  2. Definir resolve.symlinks = true na configuração do webpack dentro de next.config.js
  3. Manipulação de itens externos solicitados de library a serem solicitados de library/node_modules (para que a compilação do lado do servidor resolva os módulos corretamente)
  4. Comentando a linha https://github.com/vercel/next.js/blob/f98e38c9b634b85e6679e7b5f953a9d98074cfc3/packages/next/build/webpack-config.ts#L601

Isso funciona como pretendido, mas parece hacky, dado que Next.js está impulsionando alguns dos sites importantes como o da Apple, é possível esperar um suporte melhor para os monorepos que costumam ser usados ​​para gerenciar código compartilhado nesses grandes projetos?

Tenho brincado com isso e descobri que, quando uso um HOC, ele gera um erro, mas, se uso um componente como um invólucro, funciona bem.

Se alguém estiver interessado, tenho um repositório onde você pode reproduzir isso: next-components-hooks-error

Teste HOC - Lança erro

components/withPrivateRoute.js -> Componente de pedido superior

import React, { useEffect } from 'react';
import { useRouter } from 'next/router';
const withPrivateRoute = WrappedComponent => {

    const router = useRouter();
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const user = localStorage.getItem('user');
        console.log(user);

        if (!user) {
            router.push('/login');
        } else {
            setLoading(false);
        }

    }, []);

    return ({ ...props }) => !loading && <WrappedComponent test={test} {...props}/>;
};

export default withPrivateRoute;

pages/hoc.js -> Não funciona (página usando o HOC)

import React from 'react';
import withPrivateRoute from '../components/withPrivateRoute';

const HocTest = () => <p>Authorization HOC Test!</p>;

export default withPrivateRoute(HocTest);

Teste de componente de invólucro

components/AuthLayout.js -> Componente (invólucro)

import React, { useState, useEffect } from 'react';
import { useRouter } from 'next/router';

const AuthLayout = ({ children }) => {

    const router = useRouter();
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        const user = localStorage.getItem('user');
        console.log(user);

        if (!user) {
            router.push('/login');
        } else {
            setLoading(false);
        }

    }, []);

    return !loading && (
        <React.Fragment>
            {children}
        </React.Fragment>
    );
};

export default AuthLayout;

pages/wrapper.js -> Página usando o componente wrapper, funciona

import React from 'react';
import AuthLayout from '../components/AuthLayout';

const WrapperTest = () => (
    <AuthLayout>
        <p>Authorization Wrapper Test!</p>
    </AuthLayout>
);

export default WrapperTest;

hey @Timer, há algum progresso nisso?

Resolvo meu problema usando https://github.com/vercel/next.js/issues/9022#issuecomment -609969178 como solução.
Meus problemas eram usar meu repositório de biblioteca e yarn link ing com meu repositório de aplicativo
exemplo
package.json

{
  "dependencies": {
    "next": "9.5.1",
    "myUILibrary": "git+ssh://[email protected]/MyRepo/library-web-ui.git#master",
    "react": "16.13.1",
    "react-dom": "16.13.1"
  }
}

e eu yarn link myUILibrary ao meu checkout local MyRepo/library-web-ui que também tem react instalado.

Muito obrigado @johot por postar sua solução

5 🌟 de 3 (sim! Todas as estrelas e muito mais!)

Posso confirmar a mesma experiência de @ wasd171 em um ~9.4.4 nesse ínterim.

Estou tendo exatamente o mesmo problema com Rush + PNPM 👍

ok, eu tive um erro muito estúpido causando esse problema:

import React, { useState } from 'React';

Deve ser r eact em vez de R eact:

import React, { useState } from 'react';

Sim. Estou vendo isso também em 9.5.x - Fazer downgrade para 9.4.4 funciona - você também pode reproduzir isso com next-site

Capture

Não consegui corrigir esse erro no 9.5.2. Mas tudo funciona perfeitamente em 9.5.3 para mim, sem truques.

Não estou usando o pnpm.

Eu falei cedo demais. Também não acho que esteja funcionando com o 9.5.3.

Ele está funcionando de forma confiável no 9.5.3 para mim agora. 🤷 Não sei mais o que está acontecendo.

9.5.3 não funciona para mim - mesmo erro. Estou usando o Rush + NPM. Existe uma solução alternativa conhecida? (aliás, vamos atualizar o título porque não é mais sobre 9.0.6)

Para sua informação, foi uma das razões pelas quais minha organização decidiu mudar de npm para yarn . Apenas (infelizmente) joga muito melhor. A mudança é irritante, mas estamos muito felizes agora.

Módulos transpilados com ganchos também não funcionam para mim.

A propósito, para qualquer pessoa com esse problema ao usar next-transpile-modules e npm , escrevi uma seção de perguntas frequentes que explica o problema e as possíveis soluções: https://www.npmjs.com/package/ next-transpile-modules # i -have-trouble-with-duplicated-dependencies-or-the-invalid-hook-call-error-in-react

Consegui resolver isso adicionando manualmente a resolução da versão para yarn na raiz do projeto. Então, em vez de mover todas as dependências de reação para a raiz package.json , adicionei as seguintes linhas:

  "resolutions": {
    "react": "16.13.1",
    "react-dom": "16.13.1"
  }

Veja: https://classic.yarnpkg.com/en/docs/selective-version-resolutions/

É importante notar que, no meu caso, as compilações locais funcionaram enquanto as compilações no Vercel relataram o erro Invalid hook call .

Eu experimentei um problema semelhante em _app.js com uma página genérica nos próximos 10

image

Ei,

No meu caso, transpilei módulos que também estavam vinculados por meio de npm link .

Dependências como React precisam ser incluídas como peerDependencies vez de dependências regulares porque ele estava baixando várias instâncias dele. Portanto, se você estiver tendo o erro de ganchos inválidos, tente estas etapas:

  1. Inclua seu módulo de terceiros como uma dependência em seu projeto principal.
  2. Execute um npm install para instalar todos os seus módulos.
  3. Abra seu terminal / console e navegue até o módulo, então execute sudo npm link .
  4. Navegue de volta ao seu projeto principal e execute npm link @example/project . Você deve ver um pequeno ícone de seta próximo ao nome do módulo dentro de node_modules se estiver usando o Visual Studio Code.
  5. Execute seu npm run dev .

Novamente, você deve incluir React como peerDependency em vez de uma dependência regular em seu @ example / project.

Espero que ajude!

Eu tenho um monorepo com um projeto next.js dentro. Enfrentou o mesmo problema com uma chamada de gancho inválida após instalar storybook . Resolvi o problema seguindo a sugestão de resolutions ao nível raiz package.json :

"resolutions": {
  "react": "^17.0.1",
  "react-dom": "^17.0.1"
}

Não tenho certeza se essa será uma boa solução, uma vez que adicionarmos mais clientes e pacotes.

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