Next.js: Adicionar suporte para transpilar módulos dentro de node_modules

Criado em 9 jan. 2017  ·  103Comentários  ·  Fonte: vercel/next.js

Agora, alguns de nós enviam pacotes NPM (especialmente componentes) escritos em ES2015 sem transpilá-los.

Isso é uma coisa muito boa, especialmente se eles forem usados ​​em um projeto como Next.js ou CRA (que faz transpilação). Eles oferecem benefícios como:

  • Não há necessidade de transpilar antes de enviar para a NPM
  • Obtenha o benefício de sacudir a árvore do Webpack 2

Mas não podemos fazer isso agora, excluímos tudo dentro de node_modules da transpilação de babel.

Então, aqui está a solução proposta.

Temos uma entrada em next.config.js para incluir módulos que precisam passar pelo babel. Ver:

module.exports = {
   transpileModules: [
     "my-component",
     "redux/src"
   ]
}
story feature request

Comentários muito úteis

Quanto mais eu uso next.js sério e construo uma rica biblioteca de módulos em torno dele, mais este recurso se torna importante. Está se tornando um verdadeiro PITA replicando a etapa de compilação do babel em meus módulos internos.

🚀🤖

Todos 103 comentários

  • Por que isso não é possível com a extensão webpack() ?
  • transpileModules soa melhor
  • Aceitaremos regexps?

Por que isso não é possível com a extensão webpack ()?

Espero que você se refira à configuração personalizada do webpack. Isso é factível. Mas isso fica em um carregador existente. Conseguir isso é um pouco mais difícil.

transpileModules soa melhor

Incrível. Eu vou atualizar.

Aceitaremos regexps?
Sim. certo.

Ei,

Enquanto estou iniciando meu próprio site, estou testando novas tecnologias como Lerna / Next / Styled ... e ficaria feliz em fornecer comentários sobre isso.

Abri um problema duplicado em que tentei importar / transpilar um módulo baseado em CRA em meu módulo NextJs, mas não sabia como fazer a transpilação acontecer (observe que gostaria de manter meu módulo executável como um autônomo)

Também notei que o Babel, também baseado no Lerna, está transpilando cada módulo antes de expô-los, mas me parece melhor fazer como @arunoda sugeriu e deixar o aplicativo cliente fazer a transpilação.

Eu gostaria de ter uma única configuração de babel para meu cliente e compartilhar essa configuração com todos os meus módulos desacoplados. Isso provavelmente não é tão fácil se eu quiser manter a capacidade de executar meus módulos como autônomos, fora do Next runner

Meu projeto de teste atual está aqui: https://github.com/slorber/playground/ Vou tentar atualizá-lo assim que houver um fork / PR. @arunoda você está trabalhando nisso?

@slorber atualmente estamos nos concentrando no lançamento 2.0 e estamos ajustando as coisas e encontrando os bugs possíveis.

Ainda não comecei a trabalhar nisso, mas podemos fazer isso logo após o 2.0.

Ok, então vou fazer um garfo. Já estou executando o beta 2.0.0 porque não estou construindo um site crítico e não acho que o webpack 1.13 resolva jsnext: campo

Não sou um especialista em bundler, mas acho que prefiro usar o campo "module" do package.json, não? "main" parece para código já transpilado, tanto quanto eu sei. Mas como a configuração do webpack permite incluir / excluir a transpilação, não tenho certeza se é relevante. Alguma recomendação sobre qual dos 3 campos eu prefiro usar?

@slorber Acho que o webpack só oferece suporte a main assim como o NPM. Você pode usar isso.
Podemos verificar o caminho do arquivo na função exclude em nosso next.conf.js

Hmm, de acordo com o que vi na prática no Next 2.x, vi o módulo funcionar (mas falha mais tarde em tempo de execução porque não foi transpilado) enquanto jsnext: main não funcionou (pelo que me lembro). Mas deve ser suportado .

De qualquer forma, jsnext: main ou module não parece ser a solução para este problema, então para os módulos internos da empresa apenas habilitar a transpilação é provavelmente suficiente

A comunidade não concordou com uma abordagem, certo? Por exemplo, consegui usar react-youtube o outro fora da caixa sem problemas. Estou assumindo um grande número de módulos transpilar antes de publicar?

Ref: https://github.com/rauchg/blog/blob/master/components/post/youtube.js

Sim, faz sentido sempre transpilar antes de publicar porque você não sabe quem / como o módulo será consumido e você não quer forçar o cliente a definir as configurações de babel apropriadas para sua biblioteca. Isso é o que o Rollup sugere : publicar o módulo transpilado de diferentes maneiras para que o bundler possa decidir qual usar.

Mas para pacotes internos da empresa, as configurações de transpilação podem ser as mesmas em vários projetos (como uma predefinição de babel) e faz sentido para mim permitir que o agrupador de cliente transpile todas as dependências da empresa

Concordo plenamente com

E @rauchg / @arunoda suportando RegExp's seria muito bom, então você poderia ter uma entrada que pegasse todos os módulos internos da empresa, usando, digamos, o namespace org do NPM:

// next.config.js
module.exports = {
  transpileModules: [
    /^\@my-npm-org\/.*/
  ]
}

Bela sugestão @philcockfield

Ei, talvez valha a pena oferecer algumas predefinições. Parece-me que a maioria das ferramentas (link Lerna / npm ...) dependem de links simbólicos, então por que não algo tão simples como:

`` `javascript
module.exports = {
transpileModules: ["links simbólicos"]
}
`` ``

Quanto mais eu uso next.js sério e construo uma rica biblioteca de módulos em torno dele, mais este recurso se torna importante. Está se tornando um verdadeiro PITA replicando a etapa de compilação do babel em meus módulos internos.

🚀🤖

Estou trabalhando nisso hoje :)

@philcockfield, experimente: https://github.com/zeit/next.js/pull/749

obrigado @arunoda

Portanto, conforme comentado no seu PR, se isso não suportar links simbólicos, o recurso será um pouco limitado porque não funcionará com link npm ou Lerna, mas apenas para módulos npm que não são transpilados (certo? Não vejo nenhum outro usecase a menos que você comprometa módulos dentro de /node_modules )

Por que não oferecer suporte a links simbólicos? é mais difícil de suportar?

Também queria testar seu branch no meu aplicativo, mas não tenho certeza de qual é a melhor maneira de fazer isso. Existe algum procedimento conhecido para que possamos testar facilmente um branch e não seja muito doloroso para o testador? Eu tentei algumas coisas como:

  • npm install https://github.com/arunoda/next.js.git#add -706: falha porque a próxima pasta / bin está vazia no github repo
  • clone git da bifurcação dentro de / node_modules: sem muito sucesso (mas pode ser por causa de minhas configurações específicas do Lerna)

Qual é a melhor maneira de testar um fork atualmente?

Se você está pensando em fazer isso com next.config.js : module.exports = { webpack: (config , então config.module.rules tem algumas coisas, parece que você precisa alterar uma dessas regras ou adicionar uma? :

  { loader: 'babel-loader',
    include: '/Users/me/gh/guide/node_modules/next/dist/pages',
    options: 
     { babelrc: false,
       cacheDirectory: true,
       sourceMaps: 'both',
       plugins: [Object] } },
  { test: /\.js(\?[^?]*)?$/,
    loader: 'babel-loader',
    include: 
     [ '/Users/me/gh/guide',
       '/Users/me/gh/guide/node_modules/next/dist/pages' ],
    exclude: [Function: exclude],
    query: 
     { babelrc: true,
       cacheDirectory: true,
       sourceMaps: 'both',
       presets: [] } } ]

Olhando para a frente para a sintaxe mais simples sugerida.

Desculpe pela minha ignorância, não consigo ver qual é a resolução deste problema. Adoraríamos importar o es6 para a nossa base de código, precisamos da mudança de árvore.

Existe um PR sobre isso?

@andrewmclagan Este problema ainda está aberto e tem um PR relacionado que provavelmente não irá satisfazer a todos (como os usuários do LernaJS)

Qual é a situação disso? Existe alguma outra maneira de fazer o próximo webpack para transpilar arquivos importados de node_modules?

@slorber, vou dar uma olhada no PR. Contribua com nosso caso de uso.

Estou enfrentando um tipo de problema semelhante. Tentando usar o pacote get-urls . Funciona encontrar com dev mas quando eu compilá-lo. Eu recebi um erro do uglify

...
{ Error: commons.js from UglifyJs
...

Existe alguma solução alternativa para isso, por favor?

Arunoda vai trabalhar nisso algum dia aqui. Ele já fez antes em # 749

Eu adoraria ver esse recurso implementado. Como @philcockfield mencionou, é um cenário comum construir uma biblioteca de módulos que dependem da transpilação do Next.js, e seria ótimo poder compartilhar componentes entre projetos.

Isso não é necessário apenas para sacudir as árvores. Também para plugins babel como styled-jsx . Portanto, se você tiver um módulo (como uma biblioteca) que usa um plugin babel, a melhor solução é incluir o código-fonte ES6 e permitir que seu aplicativo o transpile de node_modules. É claro que o próximo já inclui styled-jsx por padrão.

Aqui está o que eu fiz

// next.config.js
exports.webpack = config => (config.module.rules = config.module.rules.map(({exclude, ...rest}) => ({
  exclude: Object.prototype.toString.call(exclude) === '[object Function]' ? (str => !/mycomponents/.test(str) && exclude(str)) : exclude,
  ...rest
})), config);

Basicamente, substituí cada exclude por uma função personalizada.
Não sei o que estou fazendo de errado, mas simplesmente não consigo fazer funcionar.
Preciso que o conteúdo de node_modules/mycomponents também seja transpilado por Next.js

Nem mesmo funciona se eu substituir completamente todas as exclusões por um array vazio

exports.webpack = config => (config.module.rules = config.module.rules.map(({exclude, ...rest}) => ({
  exclude: [],
  ...rest
})), config);

Por favor me ajude :)
Obrigado

Ei pessoal ( @thealjey ) Há meses que transpilo jsnext:main módulos acionados.

Não estou usando next.js mas espero que ajude.

@damianobarbati não, infelizmente não
Configurar o webpack diretamente para transpilar o que quer que não seja difícil, mas estou lutando para fazer isso funcionar no contexto do Next.js

ei todos, alguém encontrou uma solução?

Eu tenho um módulo de nó vinculado ES6 local que preciso importar no meu projeto, mas não consigo fazer o voodoo do webpack certo!

Tenho certeza de que há uma maneira melhor, mas executamos tudo por meio do babel on build:

next build && babel .next/*.js --out-dir . --presets=es2015,react

Isso morreu? Estou procurando uma maneira de transpilar um módulo personalizado e parece que ainda não é possível.

@mattfelten está no roteiro para a v5 👍

Alguém tem um exemplo de solução alternativa para isso?

@timneutkens Existe algum cronograma para isso? Aprecie que muitas vezes é uma pergunta impossível, mas estamos tentando determinar nossa pilha de trabalho a partir de agora e isso é um grande bloqueador para nós! :)

As sugestões de solução alternativa também são válidas.

@thealjey sabe que este é um comentário antigo, mas sua solução provavelmente não funcionou porque há um include especificado também que precisaria ser substituído.

Atualização: olhei para essa estratégia, mas não é sensata, dados todos os diferentes carregadores para diferentes diretórios de módulo dentro da configuração interna do next.js. Isso precisará ser de primeira classe.

@chrisui minha solução (temporária) foi usar o babel-plugin-module-resolver , configurado assim - "plugins": [["module-resolver", {"root": ["./"]}]]
não é de forma alguma uma solução perfeita, mas, como tudo o mais falhou, funciona por agora
graças a isso eu não preciso escrever um monte de ../ com cada importação
isso pode realmente ser uma solução melhor para alguns, embora certamente não ajude com a capacidade de reutilização

@thealjey você poderia dar um exemplo?
Eu tenho uma configuração de projeto onde tento fazer isso sem sucesso ...
https://github.com/jamesgorrie/nappy

Eu ficaria feliz em tentar obter um PR, pois isso tornaria nossa vida muito mais fácil, mas há algumas perguntas como: next.js suportar a transpilação de certos módulos ou isso deve ser feito pelo transpiler, mas o next.js segue a resolução do módulo mais estritamente. Não tenho certeza a quem perguntar ou por onde começar aqui, como novo em next.js .

está no roteiro para v5 👍

@timneutkens isso chegou à v5?

pensando em saber.

Basta olhar para onde ele se fundiu. isso foi mesclado há 8 dias. 5.0.0 foi lançado 2 dias atrás. do ramo de canário onde está mesclado com ...

Alguém tem um exemplo de como isso pode ser implementado? É suposto funcionar assim, conforme mencionado acima?

module.exports = {
    transpileModules: ['my-npm-module']
}

ou parece diferente?

Estou confuso. @timneutkens O link mencionado acima é para um PR que ainda está aberto. Isso ainda NÃO foi mesclado na v5?

EDIT: Não importa, este é apenas um PR para destacar o exemplo.

É um exemplo, você pode usar o exemplo sem que seja mesclado. transpileModules é algo que abordaremos mais tarde.

Como regra geral: quando um problema é aberto, ele não é liberado.

@brianyingling Transformei o exemplo em um plug-in para uma solução provisória (apenas v5).
Está funcionando para nós no momento, até que a solução oficial mais robusta seja colocada em prática.

https://www.npmjs.com/package/@weco/next -plugin-transpile-modules

Eu adoraria ver um exemplo disso para um único módulo na base de código do aplicativo.

Por exemplo, eu tenho um módulo que uso tanto no lado do servidor quanto no cliente. Não consegui fazer nenhum dos exemplos acima funcionarem, seja fatorando o módulo em seu próprio módulo separado e yarn link ing nele, seja hackeando as regras do webpack.

Aqui está uma reprodução simples: https://github.com/statico/nextjs-with-async-lib

// pages/index.js
import { foo } from '../lib/test'
export default () => <div>hello {String(typeof foo)}</div>

// lib/test.js
async function foo () {}
module.exports = { foo }

@timneutkens me diz que isso ocorre porque estou usando async/await no módulo compartilhado. Acho que minha solução pode ser remover async / await e mudar tudo para .then() -style callbacks.

OK, encontrei uma solução que funciona para mim.

Primeiro, adicionei a configuração config.resolve.symlinks = false à minha configuração next.config.js por https://github.com/zeit/next.js/issues/3018#issuecomment -380879576

// next.config.js
webpack: (config, { dev }) => {
  config.resolve.symlinks = false
  return config
}

Em seguida, coloco minha biblioteca compartilhada - um arquivo .js que usa exportações CommonJS e async / await palavras-chave - em um subdiretório do aplicativo chamado shared :

// shared/index.js
async function foo () {}
module.exports = { foo }
// shared/package.json
{
  "name": "@myapp/shared",
  "version": "1.0.0",
  "main": "index.js",
  "license": "UNLICENSED",
  "private": true,
  "dependencies": { ... }
}

E, finalmente, adicionei um script postinstall para vincular tudo junto quando alguém fizer um yarn install no aplicativo principal:

// package.json
{
  ...
  "scripts": {
    "postinstall": "cd shared ; yarn -s unlink ; yarn link && yarn && cd .. && yarn link @myapp/shared",
   ...

Agora meus testes Mocha passam no lado do servidor, meu servidor Koa customizado inicia bem e não há mais Cannot assign to read only property 'exports' of object '#<Object>' malucos em minhas páginas NextJS.

Tive o mesmo problema ao atualizar para NextJs 5.1.0. Um ou dois dos módulos de nó a seguir não estavam transpilando funções de setas grossas e lançando erros no IE11. Eu já tinha passado pela configuração de polyfills individuais e no final optei por direcionar esses arquivos de módulos com babel-polyfill em meu next.config.js com isto:

module.exports = {
  webpack: (config, { dev }) => {
    const polyfill = new Promise((resolve, reject) => {
      const originalEntry = config.entry

      originalEntry().then(entries => {
        if (entries['main.js']) {
          entries['main.js'].unshift('./client/polyfills.js')
          entries['main.js'].unshift('babel-polyfill')
        }
        config.entry = entries

        resolve()
      })
    })

    config.module.rules.push(
     {
        test: path.resolve('./node_modules/next/node_modules/'),
        loader: 'babel-loader',
        options: {
          babelrc: false,
          cacheDirectory: false,
          presets: ['es2015']  
        }
      }
    )

    return polyfill.then(() => { return config })
  }
}

Espero que isso ajude alguém.

ESM funciona perfeitamente.

Com um servidor Next.js personalizado em index.js , posso executar este comando para iniciar o servidor e o esm entra em ação perfeitamente, resolvendo os módulos ES em pacotes de projetos vinculados ao Lerna.

node -r esm index.js

@curran legal, ele pode substituir o babel-node?

@curran eu evitaria fazer isso na produção

@blackbing não sei.

@thealjey Por que isso?

Caso alguém esteja procurando uma solução rápida e fácil, aqui está o que fiz. Eu criei um subdiretório, shared/ , com qualquer código que desejamos executar no back-end por meio de script Node autônomo e cliente via NextJS. Ele tem seu próprio package.json e declara seu nome como @myproject/shared .

Em seguida, no projeto principal (pai), adicionei um script de pós-instalação a package.json como este: cd shared && yarn -s unlink >/dev/null 2>&1 ; yarn -s link && yarn -s && yarn link @myproject/shared - execute yarn pelo menos uma vez e altere suas importações para import { whatever } from '@myproject/shared/somefile'

Desta forma, o código compartilhado funciona sem nenhuma etapa de transpilação maluca, além de você não ter que executar novamente yarn / npm cada vez que fizer uma atualização, já que yarn link faz um link simbólico.

Para aqueles que usam TypeScript, @weco/next-plugin-transpile-modules não deve funcionar. Eu criei um fork para lidar com withTypescript da Next: https://github.com/KeitIG/next-plugin-transpile-modules

Ainda preciso descobrir como fazer as coisas corretamente quando precisamos ter código do lado do servidor no TypeScript também.

Alguma novidade sobre isso?

E ainda outro meu, na seguinte essência. Ele lida com TypeScript e também pacotes específicos de @scope , em vez de todos os pacotes. https://gist.github.com/trusktr/44400d0d016c506629b4f914799dc9cd

Acabei de montar um exemplo simples de trabalho que usa esm e lerna

https://github.com/curran/nextjs-esm-example

/ cc @jdalton

Pessoalmente, fiz isso funcionar com o seguinte next.config.js :

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.js$/,
      include: /node_modules/,
      use: [
        options.defaultLoaders.babel
      ]
    })

    return config
  }
}

Ele babela tudo em node_modules , que eu precisava para conseguir compatibilidade com o IE 11 ...

Eu também apreciaria uma solução para isso, lutando para adicionar pacotes npm não transpilados ao meu projeto. Tive que baixá-los para o fornecedor / por enquanto :(
Realmente irritante

@ bel0v Acho que você já deve conseguir fazer isso com next-plugin-transpile-modules . Este problema provavelmente deve ser resolvido. cc / @timneutkens

Eu ainda gostaria de investigar soluções alternativas.

Recentemente Jamie escreveu um tópico muito detalhado sobre o problema de compilar node_modules: https://twitter.com/jamiebuilds/status/1080840492525350912

Li o tópico de Jamie, embora também gostaria de compartilhar a opinião de Henry Zhu e Babel sobre essa situação e solução.
https://babeljs.io/blog/2018/06/26/on-consuming-and-publishing-es2015+-packages

(Não discordando de Tim, apenas pensei em compartilhar, muitos prós e contras. Pode ajudar Tim na investigação de soluções alternativas)

Sim, temos conversado com muitas pessoas sobre esse problema na última metade do ano, incluindo Henry 😄

Apesar das preocupações sobre a transpilação de node_modules, querer transpilar seus próprios pacotes em um monorepo é um requisito muito comum, ao qual essas preocupações não se aplicam

@dcalhoun Já tentei, mas infelizmente ainda recebo um erro inesperado de token. Há um problema aberto no Next 7 neste plug-in que pode estar relacionado

@ bel0v

Você deve ler o FAQ;) há uma solução para este problema: https://github.com/martpie/next-plugin-transpile-modules#i -have-trouble-making-it-work-with-nextjs-7

Tenho usado este plugin em vários projetos e ele faz o trabalho muito bem. O problema do Next 7 é estranho, não tenho certeza se vem do Next ou do Babel, abri um problema aqui mesmo assim: https://github.com/zeit/next.js/issues/5393

@martpie sim, acredito que já tentei .. de qualquer forma, vou tentar outra vez

@martpie , começamos a usar o next7 com um babel.config.js consistente e espaços de trabalho do yarn, posso ver se consigo configurar um exemplo simples.

Eu criei um exemplo básico aqui
https://github.com/bel0v/learnnextjs-demo
nele, instalei uma dependência não traduzida (wired-elements), recebi um erro de compilação Unhandled Rejection (SyntaxError): Unexpected token { e tentei consertar a maneira sugerida.
Estou pensando que talvez precise de alguns plug-ins adicionais do babel para que funcione .. 🤔

@ bel0v no FAQ novamente, há uma explicação sobre por que as configurações do Lerna não funcionam (TL, DR; provavelmente você está usando está errado)

@martpie ah, entendi! Não sabia que o pacote de terceiros foi configurado com Lerna. Obrigado

Parece que https://twitter.com/jamiebuilds foi suspenso, então não posso mais ler o tópico lá. # 3018 Foi encerrado em referência a este problema, então estou me perguntando quais são as abordagens alternativas que estão sendo consideradas?
Eles representam o estado da arte / melhores práticas de next.js para esses casos de uso do atm?
https://github.com/curran/nextjs-esm-example
https://github.com/wellcometrust/next-plugin-transpile-modules
https://github.com/martpie/next-transpile-modules
https://github.com/zeit/next.js/tree/canary/examples/with-yarn-workspaces

Então, se você, como eu, está trabalhando em um projeto que tem que suportar o IE11, você realmente tem que transpilar todo o código dentro de node_modules/ . No Next.js 7.x, eu estava usando a seguinte configuração, que funcionou muito bem.

Infelizmente, ele parou de funcionar no Next.js 8.x com erros de que os módulos não conseguiam importar outros módulos porque não tinham uma exportação padrão. Então eu vim com a configuração abaixo para Next.js 8.x, que apenas transpila o código em node_modules/ com @babel/preset-env , e nenhum outro plug-in.

Isso é combinado definindo minha propriedade browserlist em package.json :

  "browserslist": "defaults, IE >= 11, EDGE >= 14, Safari >= 11, Chrome >= 41, Firefox >= 52",

Próxima 7.x

next.config.js

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.js$/,
      include: /node_modules/,
      use: [
        options.defaultLoaders.babel,
      ],
    })

    return config
  },
}

Next.js 8.x

next.config.js

module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.js$/,
      include: /node_modules/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env'],
          plugins: ['@babel/plugin-syntax-dynamic-import'],
        },
      },
    })

    return config
  },
}

Infelizmente, eu ainda não descobri como usar @babel/plugin-transform-runtime com esta configuração, então provavelmente vai cuspir alguns auxiliares no código 😞 espero que o gzip cuide disso 😆 😅


Eu acho que seria incrível se Next.js pudesse nos dar a opção de transpilar corretamente node_modules/ para trabalhar com qualquer browserlist você tenha. Parece que todos os grandes sites que têm usuários corporativos dependem disso para oferecer suporte adequado a navegadores mais antigos.

Como mantenedor de next-transpile-modules (baseado no incrível trabalho de @jamesgorrie), estou feliz em ajudar qualquer pessoa que esteja enfrentando esse problema aqui.

Tenho trabalhado em projetos profissionais por mais de um ano com este plugin e até agora ele funcionou bem.

O suporte nativo do Next.js seria, com certeza, incrível e eu ficaria feliz em ajudar a integrar esse recurso no pacote next . Eu sei que Tim tinha algumas idéias que queria experimentar, mas de qualquer maneira.

Saúde!

@martpie Eu rapidamente olhei para o seu projeto, mas não encontrei uma maneira rápida de transpilar _todos_ os módulos, isso é possível? ☺️

Além disso, vejo que você está escolhendo options.defaultLoaders.babel e usando isso como o carregador de babel. Ao fazer isso com Next.js 8.x, tive o problema de alguns módulos não serem devidamente reconhecidos como um módulo CJS depois disso e outras libs não conseguirem importá-los, por exemplo:

./pages/_glamor.js
Attempted import error: 'css' is not exported from 'glamor'.

./components/project-selector.js
Attempted import error: 'react-select/lib/Async' does not contain a default export (imported as 'AsyncSelect').

./node_modules/react-select/dist/react-select.esm.js
Attempted import error: 'react-input-autosize' does not contain a default export (imported as 'AutosizeInput').

./pages/signup/full.js
Attempted import error: 'react-select/lib/Creatable' does not contain a default export (imported as 'CreatableSelect').

./components/markdown-editor.js
Attempted import error: 'react-simplemde-editor' does not contain a default export (imported as 'SimpleMDEEditor').

./components/pagination.js
Attempted import error: 'react-js-pagination' does not contain a default export (imported as 'UpstreamPagination').

./node_modules/react-google-recaptcha/lib/es/recaptcha-wrapper.js
Attempted import error: 'react-async-script' does not contain a default export (imported as 'makeAsyncScriptLoader').

./pages/_glamor.js
Attempted import error: 'rehydrate' is not exported from 'glamor'.

É por isso que mudei para fornecer uma configuração de babel personalizada para node_modules/ , que apenas transpila o código usando preset-env e ignora as transformações específicas de Next.js. O que você acha dessa abordagem?

Saúde 🍻

@LinusU Talvez tente transpileModules: ['(.*?)'] e me diga se funciona?

Mas pode não estar funcionando em uma versão principal futura, então tome cuidado.

De forma mais geral, eu não recomendo (leia "altamente desencorajado") transpilar a pasta node_modules inteira, demorará uma eternidade para compilar e os pacotes devem fornecer código compatível com ES3 (compatível com o IE11).

Transpile apenas o módulo que você precisa! (como lodash-es , módulos locais etc ...)

os pacotes devem fornecer código compatível com ES3 (compatível com o IE11).

Esta não é a realidade que eu vi, e na verdade não concordo. Os autores do módulo nunca saberão exatamente quais navegadores estou visando, e se eles enviarem códigos mais antigos, eles potencialmente penalizarão os usuários que visam navegadores modernos.

vai demorar uma eternidade para compilar

É um pouco lento na inicialização para mim, mas depois disso, parece estar em cache e, ao fazer alterações em uma página específica, vejo recarregamentos quase instantâneos.

Transpile apenas o módulo que você precisa!

Isso exigiria que eu soubesse exatamente quais pacotes são compatíveis com o IE11 e quais não são, além de manter essas informações atualizadas a qualquer momento em que qualquer dependência (até mesmo dependências temporárias) mude. Não vejo como isso é realista 🤔

O importante é que os pontos de entrada ESM fornecidos em package.json module são comumente ES5 com ES6 importações / exportação para agitação de árvore. Portanto, este é o trabalho de um bundler (Webpack) e não de um transpiler (Babel), a menos que indicado de outra forma. Muitos pacotes bem mantidos já possuem pontos de entrada ESM, por exemplo, redux/es para Redux que foi mencionado pelo OP.

Se você está pensando em fazer isso com next.config.js : module.exports = { webpack: (config , então config.module.rules tem algumas coisas, parece que você precisa alterar uma dessas regras ou adicionar uma? :

  { loader: 'babel-loader',
    include: '/Users/me/gh/guide/node_modules/next/dist/pages',
    options: 
     { babelrc: false,
       cacheDirectory: true,
       sourceMaps: 'both',
       plugins: [Object] } },
  { test: /\.js(\?[^?]*)?$/,
    loader: 'babel-loader',
    include: 
     [ '/Users/me/gh/guide',
       '/Users/me/gh/guide/node_modules/next/dist/pages' ],
    exclude: [Function: exclude],
    query: 
     { babelrc: true,
       cacheDirectory: true,
       sourceMaps: 'both',
       presets: [] } } ]

Olhando para a frente para a sintaxe mais simples sugerida.

Funciona bem para mim

{
    test: /\.js(\?[^?]*)?$/,
    loader: 'babel-loader',
    include: [
        path.resolve(__dirname, './node_modules/next/dist/pages'),
    ],
    query: {
        cacheDirectory: true,
        sourceMaps: 'both',
        presets: ['@babel/preset-env'],
        plugins: ['@babel/plugin-proposal-object-rest-spread']
    }
},

Eu encontrei esse problema usando um repositório mono Lerna e estava coçando minha cabeça para saber qual era a causa. Como o erro está vindo do webpack, ele não dá bons detalhes, além de que está faltando um carregador, o que não ajuda. Felizmente encontrei este problema no github!

Vou deixar minha solução aqui para qualquer outra pessoa que pesquisar esse problema e também estiver usando o Lerna:

Crie um script de pré-publicação para o pacote compartilhado que transpila a fonte em um diretório dist e diga a Lerna para apontar para o diretório dist ao vincular:

// package.json
"main": "dist",
"scripts": {
  // I'm using the react-app preset because it's easy
  "prepublish": "babel --presets react-app --plugins @babel/plugin-transform-modules-commonjs src --out-dir dist"
},
// This instructs Lerna to use dist when symlinking
"publishConfig": {
  "directory": "dist"
}

Agora, quando você lerna bootstrap ele executará o script de pré-publicação e transpilará a fonte para que o Next possa consumi-la.

Se você estiver usando lerna você pode fazer links simbólicos para serem transpilados usando next-transpile-modules . Como usar esse pacote com lerna está escrito na parte inferior da documentação.

Para qualquer pessoa procurando por compartilhamento de código em aplicativos NextJs, eu só gosto de relatar que a solução da @LinusU funcionou para mim ao tentar compartilhar componentes e utilitários React entre vários aplicativos NextJs em meu repo mono:

// next.config.js
const aliasPathsToResolve = [
    { name: 'components', path: path.resolve(__dirname, './components') },
    { name: 'Common', path: path.resolve(__dirname, '../../common/react/') },
]
module.exports = () => {
    return  {
        webpack(config, { defaultLoaders }) {
            config.module.rules.push({
            test: /\.(js|jsx)$/,
            include: [path.resolve(__dirname, '../../common/react/')],
            use: [defaultLoaders.babel],
        })

            /** Resolve aliases */
        aliasPathsToResolve.forEach((module) => {
            config.resolve.alias[module.name] = module.path
        })
        }
    }
}

Estou usando a versão mais recente do NextJs no momento desta postagem.

@ Lwdthe1 Tentei seu código e inicialmente recebi este erro:

TypeError: Cannot read property 'then' of undefined
    at getBaseWebpackConfig (/c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/build/webpack-config.js:85:25)
    at async Promise.all (index 0)
    at async HotReloader.start (/c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/server/hot-reloader.js:14:1675)
    at async DevServer.prepare (/c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/server/next-dev-server.js:7:223)
    at async /c2/wiz-frontend/packages/pipeline-view/node_modules/next/dist/cli/next-dev.js:22:359

Fiz alguns ajustes e acabou assim:

const path = require("path");

const libPath = "../components/src"
const aliasPathsToResolve = [
  { name: "Common", path: path.resolve(__dirname, libPath) }
];

module.exports = {
  webpack: (config, { defaultLoaders }) => {
    config.module.rules.push({
      test: /\.(js|jsx)$/,
      include: [path.resolve(__dirname, libPath)],
      use: [defaultLoaders.babel]
    });

    /** Resolve aliases */
    aliasPathsToResolve.forEach(module => {
      config.resolve.alias[module.name] = module.path;
    });
    return config
  }
};

Mas ocorreu outro erro:

export { default as NavBar } from "./NavBar/NavBar"
^^^^^^

SyntaxError: Unexpected token 'export'
    at wrapSafe (internal/modules/cjs/loader.js:1055:16)
    at Module._compile (internal/modules/cjs/loader.js:1103:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1159:10)
....

que parece ter sido enfrentado antes em # 2850 e # 883.

Portanto, parece que a única solução é: https://github.com/martpie/next-transpile-modules#but -i-really-need-to-make-it-work-with-lerna

Pelo que ouvi, será apresentado o RFC em breve como o Next.js está planejando resolver esse problema, mas se alguém precisar consertá-lo agora, publiquei no npm minha solução em https://github.com/ zeit / next.js / pull / 10098 que você pode usar colocando o seguinte em package.json:

    "next": "npm:@sheerun/[email protected]",

e seguindo para next.config.js:

  babelIncludeRegexes: [/turf/],

(no meu caso, eu precisava que todos os arquivos turf fossem pré-compilados com o babel)

Este problema tem algum progresso?

Eu uso next.js 9.2.0, mas a opção babelIncludeRegexes não está funcionando

Este problema tem algum progresso?

next-transpile-modules pretende resolver este problema exatamente, você tentou?

Olá @martpie ,

Já resolvi meu problema de edição de arquivo .babelrc. Eu me refiro a esse problema

Valeu

@martpie Estou usando next-transpile-modules mas ainda assim, estou enfrentando o erro abaixo enquanto tento construir o aplicativo. Estou usando o monorepo com base de código compartilhada. Tentando acessar componentes de compartilhados como '@ myapp / shared / components / componentname.js'. Estou usando nextjs 9.xe custom next.config.js .

Erro
`
A análise do módulo falhou: token inesperado (12: 4)
Você pode precisar de um carregador apropriado para lidar com este tipo de arquivo; atualmente, nenhum carregador está configurado para processar este arquivo. Veja https://webpack.js.org/concepts#loaders
| const Spinner = props => {
| const renderDefaultSpinner = (spinnerClass, {... others}) => (
>


| );
|

Ocorreu um erro de compilação
Erro:> A compilação falhou devido a erros do webpack
`

next.config.js
const withTM = require('next-transpile-modules')(['<strong i="26">@myapp</strong>']); module.exports = withPlugins([withTM, withBundleAnalyzer], { ... }

Por favor, ajude o que estou fazendo de errado aqui.

@ raghav1086 Você pode abrir um problema no repo? ;) evitará barulho para as pessoas aqui.

+1

Eu tenho um diretório src/ para meu projeto e lib/ para uma estrutura inicial que exporta alguns utils / wrappers comuns que eu reutilizo em alguns aplicativos nextjs diferentes (meu ponto de partida)

lib não é notado quando eu inicio o servidor de desenvolvimento. quaisquer componentes da lib / não passam pelo carregador e dão um erro

Usei uma variação da solução de @ Lwdthe1 (https://github.com/zeit/next.js/issues/706#issuecomment-569041997) para corrigir o problema src e lib em meu comentário acima. Basicamente a mesma coisa, exceto que usa config.resolve.modules vez de percorrer o array aliasPathsToResolve .

  webpack: (config, options) => {
    config.resolve.modules = [
      './src/',
      './lib/',
      'node_modules'
    ];

    config.module.rules.push({
      test: /\.(js|jsx)$/,
      include: [path.resolve(__dirname, './lib/')],
      use: [options.defaultLoaders.babel],
    });

Qual é a solução de trabalho para lerna, nextjs e babel atualmente?

Estou tentando evitar a pré-transpilação de minhas bibliotecas antes de importar, e cheguei a uma conclusão difícil com todas as soluções aqui. Aqui está o que não consigo fazer funcionar:

  • next-transpile-modules .
  • redefinir as configurações de env predefinidas.
  • atualizando as regras next-babel-loader include e exclude para passar / falhar respectivamente.

@mikestopcontinues next-transpile-modules funcionou fora da caixa para mim com o TypeScript.

@calebmpeterson e @martpie (vejo vocês! 👀). Eu circulei de volta para o plug, e o problema parece ser que não há como fazer referência a submódulos. Por exemplo, o padrão '@ mono / components' não suporta a importação de '@ mono / components / Div' ou qualquer outra coisa. E especificar '@ mono / components / Div' como o padrão também não funciona ... não que eu queira fazer isso para todos os componentes compartilhados. Também tentei fazer a engenharia reversa da geração de regex para criar padrões de correspondência e, embora a regex de saída funcione, algo mais está acontecendo nos bastidores que não está.

Idealmente, eu gostaria apenas de especificar '@ mono` para cuidar de tudo e deixar meu package.json como a única fonte de verdade da qual cada um dos meus aplicativos depende. Da mesma forma, gostaria de evitar manter arquivos de índice que importam / exportam tudo em cada uma das minhas bibliotecas apenas para poder acessar submódulos.

Para voltar, acredito que o problema atual poderia ser totalmente resolvido se houvesse alguma maneira de passar rootMode: 'upward' por next-babel-loader , de modo que o babel pudesse lidar com a lógica de transpilação. Talvez isso abra outras questões relacionadas ao Next, mas a raiz do problema parece ser a maneira atípica que o Next está emaranhado em webpack e babel. Certamente, há uma maneira de deixar babel-loader separado da lógica adicional do Next?

Apenas uma atualização na frente next-transpile-modules . Eu havia diagnosticado erroneamente o erro. Nenhuma importação funciona usando este método (índice ou submódulo) se você precisa de uma configuração .babelrc . As configurações personalizadas simplesmente não são aplicadas ao código necessário. Este é novamente um problema de rootMode: 'upward' .

@mikestopcontinues Você precisa usar babel.config.js (configuração global) com next-transpile-modules , e não .babelrc (configuração local), é explicado no FAQ;)

@martpie Você não tem ideia de como estou envergonhado. Tive que ter lido essa linha uma dúzia de vezes nas últimas semanas e nunca me preocupei em clicar no problema. Isso funcionou totalmente. Obrigado!

next-transpile-modules quebrou React para mim. Agora eu uso ganchos inválidos, enquanto transpilei TRÊS módulos de exemplo

Alguém poderia reiterar qual é a melhor configuração para fazer a transpilação funcionar. Não entendo o que tenho que escrever em babel.config.js

@masbaehr na maioria dos casos, apenas adicionando next-transpile-modules à sua configuração next.config

O único problema é que next-transpile-modules não oferece suporte ao Yarn 2 pnp.

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