Next.js: Polyfill Babel não parece ser injetado

Criado em 5 jul. 2017  ·  34Comentários  ·  Fonte: vercel/next.js

Estou tentando oferecer suporte ao IE11 para meu aplicativo para corrigir o erro
TypeError: Object doesn't support property or method 'find'

Usando o próximo 2.4.6 mas também não está funcionando no beta mais recente

Adicionado um .babelerc personalizado junto com babel-preset-env com a seguinte configuração:

{
  "presets": [
    "es2015",
    "react",
    "next/babel",
    "stage-0",
    [ "env", {
      "targets": {
        "safari": 10,
        "ie": 11
      },
      "modules": false,
      "useBuiltIns": true,
      "debug": true
    }]
  ],
}

Habilitado o sinalizador de depuração, então, na inicialização, obtenho o seguinte log, o que parece significar que os polyfill foram adicionados.

babel-preset-env: `DEBUG` option

Using targets:
{
  "safari": "10",
  "ie": "11"
}

Modules transform: false

Using plugins:
  check-es2015-constants {"ie":"11"}
  transform-es2015-arrow-functions {"ie":"11"}
  transform-es2015-block-scoping {"ie":"11"}
  transform-es2015-classes {"ie":"11"}
  transform-es2015-computed-properties {"ie":"11"}
  transform-es2015-destructuring {"ie":"11"}
  transform-es2015-duplicate-keys {"ie":"11"}
  transform-es2015-for-of {"ie":"11"}
  transform-es2015-function-name {"ie":"11"}
  transform-es2015-literals {"ie":"11"}
  transform-es2015-object-super {"ie":"11"}
  transform-es2015-parameters {"ie":"11"}
  transform-es2015-shorthand-properties {"ie":"11"}
  transform-es2015-spread {"ie":"11"}
  transform-es2015-sticky-regex {"ie":"11"}
  transform-es2015-template-literals {"ie":"11"}
  transform-es2015-typeof-symbol {"ie":"11"}
  transform-es2015-unicode-regex {"ie":"11"}
  transform-regenerator {"ie":"11"}
  transform-exponentiation-operator {"safari":"10","ie":"11"}
  transform-async-to-generator {"safari":"10","ie":"11"}
  syntax-trailing-function-commas {"ie":"11"}

Using polyfills:
  es6.typed.array-buffer {"ie":"11"}
  es6.typed.int8-array {"ie":"11"}
  es6.typed.uint8-array {"ie":"11"}
  es6.typed.uint8-clamped-array {"ie":"11"}
  es6.typed.int16-array {"ie":"11"}
  es6.typed.uint16-array {"ie":"11"}
  es6.typed.int32-array {"ie":"11"}
  es6.typed.uint32-array {"ie":"11"}
  es6.typed.float32-array {"ie":"11"}
  es6.typed.float64-array {"ie":"11"}
  es6.map {"ie":"11"}
  es6.set {"ie":"11"}
  es6.weak-map {"ie":"11"}
  es6.weak-set {"ie":"11"}
  es6.reflect.apply {"ie":"11"}
  es6.reflect.construct {"ie":"11"}
  es6.reflect.define-property {"ie":"11"}
  es6.reflect.delete-property {"ie":"11"}
  es6.reflect.get {"ie":"11"}
  es6.reflect.get-own-property-descriptor {"ie":"11"}
  es6.reflect.get-prototype-of {"ie":"11"}
  es6.reflect.has {"ie":"11"}
  es6.reflect.is-extensible {"ie":"11"}
  es6.reflect.own-keys {"ie":"11"}
  es6.reflect.prevent-extensions {"ie":"11"}
  es6.reflect.set {"ie":"11"}
  es6.reflect.set-prototype-of {"ie":"11"}
  es6.promise {"ie":"11"}
  es6.symbol {"ie":"11"}
  es6.object.assign {"ie":"11"}
  es6.object.is {"ie":"11"}
  es6.function.name {"ie":"11"}
  es6.string.raw {"ie":"11"}
  es6.string.from-code-point {"ie":"11"}
  es6.string.code-point-at {"ie":"11"}
  es6.string.repeat {"ie":"11"}
  es6.string.starts-with {"ie":"11"}
  es6.string.ends-with {"ie":"11"}
  es6.string.includes {"ie":"11"}
  es6.regexp.flags {"ie":"11"}
  es6.regexp.match {"ie":"11"}
  es6.regexp.replace {"ie":"11"}
  es6.regexp.split {"ie":"11"}
  es6.regexp.search {"ie":"11"}
  es6.array.from {"ie":"11"}
  es6.array.of {"ie":"11"}
  es6.array.copy-within {"ie":"11"}
  es6.array.find {"ie":"11"}
  es6.array.find-index {"ie":"11"}
  es6.array.fill {"ie":"11"}
  es6.array.iterator {"ie":"11"}
  es6.number.is-finite {"ie":"11"}
  es6.number.is-integer {"ie":"11"}
  es6.number.is-safe-integer {"ie":"11"}
  es6.number.is-nan {"ie":"11"}
  es6.number.epsilon {"ie":"11"}
  es6.number.min-safe-integer {"ie":"11"}
  es6.number.max-safe-integer {"ie":"11"}
  es6.math.acosh {"ie":"11"}
  es6.math.asinh {"ie":"11"}
  es6.math.atanh {"ie":"11"}
  es6.math.cbrt {"ie":"11"}
  es6.math.clz32 {"ie":"11"}
  es6.math.cosh {"ie":"11"}
  es6.math.expm1 {"ie":"11"}
  es6.math.fround {"ie":"11"}
  es6.math.hypot {"ie":"11"}
  es6.math.imul {"ie":"11"}
  es6.math.log1p {"ie":"11"}
  es6.math.log10 {"ie":"11"}
  es6.math.log2 {"ie":"11"}
  es6.math.sign {"ie":"11"}
  es6.math.sinh {"ie":"11"}
  es6.math.tanh {"ie":"11"}
  es6.math.trunc {"ie":"11"}
  es7.array.includes {"ie":"11"}
  es7.object.values {"safari":"10","ie":"11"}
  es7.object.entries {"safari":"10","ie":"11"}
  es7.object.get-own-property-descriptors {"safari":"10","ie":"11"}
  es7.string.pad-start {"ie":"11"}
  es7.string.pad-end {"ie":"11"}
  web.timers {"safari":"10","ie":"11"}
  web.immediate {"safari":"10","ie":"11"}
  web.dom.iterable {"safari":"10","ie":"11"}

No entanto, em tempo de execução, ainda recebo o erro no IE11 quando chamo o método .find () em uma matriz.

Posso fazer algo para verificar se os polyfills foram injetados corretamente?

bug

Comentários muito úteis

A única correção que tenho é adicionar um layout.js personalizado e adicionar
<script src='https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js' />

Todos 34 comentários

A única correção que tenho é adicionar um layout.js personalizado e adicionar
<script src='https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js' />

@arunoda Já vimos isso antes, certo 🤔

Como uma correção, você pode fazer isso:

import 'core-js/fn/array/find'

const test = ['hi', 'there'].find(item => item === 'hi')

export default () => (
  <div>{test}, welcome to next.js!</div>
)

Deixe-me ver o que está acontecendo aqui.

Eu verifiquei isso com um aplicativo babel normal e o comportamento é o mesmo.
Você precisa adicionar o polyfill como mencionei acima.

Portanto, estou encerrando isso, pois não é exatamente um problema específico do Next.

Mas estou aberto a mais sugestões.
Sinta-se à vontade para reabrir.

@arunoda Eu tentei esse hotfix com import 'core-js/fn/array/find' dentro do _document.js para consertá-lo para todos os arquivos, mas não funcionou para o IE11.

Eu tive que ir com a solução para incluí-lo assim:
<script src='https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.23.0/polyfill.min.js' />

Estou usando Next.js V3.0.6.

Alguma ideia de como eu poderia resolver isso de uma forma mais legal?

Olá a todos.
Eu experimentei a propriedade de entrada em next.config.js .
Isso é o que eu tenho
(de acordo com https://github.com/zeit/next.js/blob/master/server/build/webpack.js#L42):

module.exports = {
  // eslint-disable-next-line no-unused-vars
  webpack(config, _) {
    const entry = async () => {
      const resolvedEntry = await config.entry()
      const entryWithPolyfill = Object.assign(
        { 'babel-polyfill': ['babel-polyfill'] },
        resolvedEntry
      )
      // console.log(entryWithPolyfill)
      return entryWithPolyfill
    }
    return Object.assign(
      config,
      entryWithPolyfill
    )
  }
}

Infelizmente este arquivo não será transpilado pelo babel, por isso ainda não funciona .

A melhor coisa seria incluir babel-polyfill na configuração do webpack do Next? É bastante comum incluí-lo.

@arunoda o que você acha?

alguma atualização sobre isso? Incluir o polyfill não é a melhor solução

Também estou interessado nisso 🤔

Corrigi esta importação de polyfills do Babel:

import 'babel-polyfill';

Importar todo o babel-polyfill é extremamente desperdiçador e seria um padrão ruim para next.js, imho. Ele adiciona 87kb ao pacote, não importa se você realmente precisa de algum dos recursos polyfilled ou não.

@sholzmayer onde você usou import 'babel-polyfill'; . Tentei no _document.js, mas não ajudou

@klaemo então qual é a sua sugestão?

Adicionar transform-runtime a .babelrc plug-ins parece funcionar para mim. Estamos desenvolvendo um aplicativo para Opera 36 que não tem Object.entries embutido.

"plugins": [
    "transform-runtime"
]

@hugotox como um desenvolvedor de aplicativos, você pode usar https://polyfill.io para carregar apenas os polyfills necessários ou fazer isso manualmente. Em nosso aplicativo, temos um polyfills.js que se parece com isto:

// Language features presented by https://github.com/zloirock/core-js
import 'core-js/fn/object/assign'
import 'core-js/fn/string/ends-with'
import 'core-js/fn/string/starts-with'
import 'core-js/fn/string/includes'
import 'core-js/fn/array/includes'
import 'core-js/fn/weak-map'

// browser features
import 'raf/polyfill'
import 'isomorphic-fetch'
import 'js-polyfills/url'

Alternativamente, nextjs pode importar e agrupar todos os polyfills de que precisa de core-js .

@igimanaloto esta solução funcionou para mim

Eu também uso o plugin transform-runtime mas recebo o erro no IE por algum motivo.

{
  "plugins": [
    "source-map-support",
    "transform-runtime"
  ],
  "presets": [
    ["env", {
      "targets": {
        "node": "6.10"
      }
    }],
    ["stage-3"],
    [
      "next/babel",
      {
        "styled-jsx": {
          "optimizeForSpeed": true,
          "vendorPrefixes": true,
          "sourceMaps": true,
          "plugins": [
            "styled-jsx-plugin-sass"
          ]
        }
      }
    ]
  ]
}

@bliitzkrieg Não importe babel-polyfill em _document.js , porque _document.js só é renderizado no servidor.

Normalmente, é recomendável incluí-lo em seu layout, basicamente qualquer arquivo que seja carregado por todas as páginas servirá bem.

Atualização: Corrigido meu exemplo para IE 10, 11: mudou a dependência de core-js/library/fn/object/assign em client/polyfill.js para core-js/fn/object/assign (como @klaemo tinha - não


Aqui está uma tentativa Dockerizada de next 5.1.0 de empregar uma combinação da abordagem indicada por @klaemo acima e um exemplo oficial, canary / examples / with-polyfills :

[Pergunta original] Qual é o uso de core-js em meu arquivo client / polyfills.js que me leva ao IE11? (Posso esperar que a abordagem prossiga a partir de uma importação que cubra tudo o que está faltando no IE11 e, em seguida, reduza gradualmente o intervalo para apenas os itens de que o aplicativo precisa.)

Aqui está o resultado inicial Eu verifiquei o resultado em algumas combinações de navegador OS + (no Browserstack) e ele falha quando estava falhando no Windows 10 + IE11 (mostrado abaixo), e talvez outras combinações do IE.

screen shot 2018-04-21 at 3 49 31 pm

Eu estava tentando executar next 5.1.0 no Chrome 43 com um servidor personalizado, .babelrc e configuração do webpack. import 'core-js/fn/object/assign'; fez o truque.

Parece que esse bug ainda existe! Estou enfrentando o mesmo problema no IE 11 e nenhuma das soluções está ajudando. O problema parece ser o pacote ansi-regex que usa uma função de seta e esta sendo uma dependência de next.js.

@arunoda @timneutkens podemos reabrir este problema?

Sim ainda existe. Estou usando resoluções de fio para fazer downgrade

import 'core-js/fn/object/assign' funcionou para mim também.

Tive que adicionar core-js primeiro ( yarn add core-js ) - claro.

Achei isso útil: https://github.com/aspnet/JavaScriptServices/wiki/Supporting-Internet-Explorer-11- (or-mais antigo)

Adicione uma documentação oficial sobre a transpilação ES6 para módulos de nó.

aqui está uma solução alternativa, mas esse bug precisa ser reaberto. @arunoda

Eu tive erros com Object.assign, String.endsWith em ie11 (em [email protected])

const {basedir} = require ('./ server / config');

// polyfills necessários para navegadores não permanentes (principalmente isto é)
const polyfills = [
'core-js / fn / object / assign',
'core-js / fn / string / ends-with',
'core-js / fn / string / starts-with',
'core-js / fn / string / includes',
'core-js / fn / array / includes',
'core-js / fn / mapa fraco',
];

module.exports = {
  webpack: (config, {dev, isServer}) => {
    const originalEntry = config.entry;
    if (!isServer) {
      config.entry = async () => {
        const entries = await originalEntry();
        Object.values(entries).forEach(entry => {
          entry.unshift(...polyfills);
          if (dev) {
            entry.unshift('eventsource-polyfill');
          }
        });
        return entries;
      };
    }

    return config;
  },
};

na verdade eu às vezes consigo

Cannot redefine non-configurable property 'endsWith'

Segui este exemplo para incluir polyfills.
Para o IE11 funcionar, eu tive que incluir estes em meu client/polyfills.js :

import 'core-js/es6/map';
import 'core-js/es6/set';

import 'core-js/fn/object/assign';
import 'core-js/fn/string/ends-with';
import 'core-js/fn/string/starts-with';
import 'core-js/fn/string/includes';
import 'core-js/fn/array/includes';
import 'core-js/fn/array/find';

import 'core-js/fn/number/is-finite';

Não tenho certeza se há algumas bibliotecas que, por exemplo, precisam do isFinite, mas meu aplicativo é mínimo.

Isso funciona, mas é muito complicado descobrir quais polyfills são realmente necessários.

Alguém sabe qual polyfill é necessário para fazer a sintaxe da classe funcionar no IE11?

classe Foo extends ...

em seus polyfills, descomente 'import' core-js / es6 / object ';' linha

Eu segui o exemplo que você mencionou @peec e funcionou para mim.

@peec este é o comportamento esperado, entretanto? Por que eu precisaria re-polyfill algo que foi incluído?

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