Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom polyfills sometimes do not work in IE11 #10794

Closed
voronianski opened this issue Mar 2, 2020 · 18 comments
Closed

Custom polyfills sometimes do not work in IE11 #10794

voronianski opened this issue Mar 2, 2020 · 18 comments

Comments

@voronianski
Copy link

voronianski commented Mar 2, 2020

In IE11 our custom scripts/polyfills.js sometimes do not work.

Desciption

Here's contents of scripts/polyfills.js:

import 'core-js';
import 'react-app-polyfill/ie9';

console.log('MY POLYFILL!');

Here's contents of next.config.js:

const withTM = require('next-transpile-modules');
const withPlugins = require('next-compose-plugins');
const withBundleAnalyzer = require('@next/bundle-analyzer');
const withSourceMaps = require('@zeit/next-source-maps');

const nextConfiguration = {
  experimental: {
    granularChunks: true,
    modern: false
  },
  useFileSystemPublicRoutes: false,
  poweredByHeader: false,
  webpack: (config, { defaultLoaders }) => {
    const originalEntry = config.entry;

    config.entry = async () => {
      const entries = await originalEntry();

      if (
        entries['main.js'] &&
        !entries['main.js'].includes('./scripts/polyfills.js')
      ) {
        entries['main.js'].unshift('./scripts/polyfills.js');
      }
      return entries;
    };

    config.module.rules.push({
      test: /\.svg$/,
      use: [
        defaultLoaders.babel,
        {
          loader: 'react-svg-loader'
        }
      ]
    });

    return config;
  }
};

module.exports = withPlugins(
  [
    [withTM, { transpileModules: ['ui-lib'] }],
    [withSourceMaps(), { devtool: 'source-map' }],
    [withBundleAnalyzer, { enabled: process.env.ANALYZE === 'true' }]
  ],
  nextConfiguration
);

Error example -

image

Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20ref%2C%20props%2C%20_owner%7D&args[]=

Scripts in html look like this -

image

Our custom polyfill is part of main.js which is loaded after frameworks.js bundle (the place where React is). If you can see both scripts are async meaning that sporadically frameworks.js loads first which ends in error.

If we include <script src="https://cdn.polyfill.io/v2/polyfill.min.js" /> in the head of the page error disappears.

Question - what's the new way to use custom polyfills with Next.js 9.2.2 and granular chunks built-in?

Thanks in advance!

System information

  • OS: Windows 10
  • Browser: Internet Explorer 11
  • Version of Next.js: 9.2.2

Additional context

Is this still up to date - https://github.com/zeit/next.js/tree/canary/examples/with-polyfills ?

@voronianski
Copy link
Author

the workaround that worked for us -

  webpack: (config) => {
    const originalEntry = config.entry;

    config.entry = async () => {
      const entries = await originalEntry();

      // add custom polyfills into specific next.js bundle
      // https://github.com/zeit/next.js/issues/10794
      const nextPolyfillPath = 'static/runtime/polyfills.js';
      const nextPolyfills = entries[nextPolyfillPath];
      if (nextPolyfills) {
        entries[nextPolyfillPath] = [nextPolyfills, './scripts/polyfills.js'];
      }

      return entries;
    };
  }

@timneutkens
Copy link
Member

FWIW the polyfills you're showing:

import 'core-js';
import 'react-app-polyfill/ie9  ';

Will not be needed when 9.3 is out (or if you use next@canary currently). As all needed polyfills are included.

@Timer
Copy link
Member

Timer commented Mar 3, 2020

Also, you're relying on a internal Next.js implementation detail that may change at any time—this is not covered by semver:

// This is reserved for Next.js use only
const nextPolyfillPath = 'static/runtime/polyfills.js';

@voronianski
Copy link
Author

voronianski commented Mar 3, 2020

Also, you're relying on a internal Next.js implementation detail that may change at any time—this is not covered by semver

@Timer, yes it's not the best way but unfortunately we couldn't find a better one. Is it possible to introduce a custom webpack entry in next.config.js?

FWIW the polyfills you're showing:
Will not be needed when 9.3 is out (or if you use next@canary currently). As all needed polyfills are included.

@timneutkens that's good but we actually encountered another issue. You're forcing polyfills to be always noModule https://github.com/zeit/next.js/blob/master/packages/next/pages/_document.tsx#L637.

It means that if we put our own polyfills inside Next.js polyfill (e.g. IntersectionObserver polyfill) it will not load in browser that support noModule but doesn't support the feature (e.g. Safari 11 - https://caniuse.com/#search=nomodule).

This leads to very ugly solutions like extending the NextScript and overwriting getPolyfillScripts function 😬

@Timer
Copy link
Member

Timer commented Mar 3, 2020

You're forcing polyfills to be always noModule

This is because you're using a private Next.js API and not the suggested method that the with-polyfills example showcases.

To clarify my previous comment, do not edit the static/runtime/polyfills.js entrypoint.
It will break.

@Timer
Copy link
Member

Timer commented Mar 3, 2020

Next.js 9.3 will mostly solve this, and the default recommendation for polyfill inclusion will be to import in the top of pages/_app.js.

Can you try upgrading to next@canary?

@voronianski
Copy link
Author

This is because you're using a private Next.js API and not the suggested method that the with-polyfills example showcases.

@Timer I've explained the problem with with-polyfills example in the initial comment - #10794 (comment)

in short - when custom polyfill is part of main.js bundle it is sometimes loaded after frameworks.js bundle and produces React error -

Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7B%24%24typeof%2C%20type%2C%20key%2C%20ref%2C%20props%2C%20_owner%7D&args[]=

@Timer
Copy link
Member

Timer commented Mar 3, 2020

Yup, the recommendation is still to use the with-polyfills example.

Figuring out why the Frameworks bundle being evaluated before the Main bundle having an effect is what needs investigated (this is speculation, right?).

Rendering should still be suspended until main.js loads, so I'm not sure why React would complain in this case (unless something reads globals once during module initialization).

@Timer
Copy link
Member

Timer commented Mar 3, 2020

We have multiple production integration tests that ensures Next.js works in IE11.

Can you please provide a fully reproducible demo so we can help debug this?

@voronianski
Copy link
Author

voronianski commented Mar 3, 2020

Can you please provide a fully reproducible demo so we can help debug this?

I will prepare something

@voronianski
Copy link
Author

just a note that this problem - #10794 (comment) was not the case in Next.js v9.0.5

@mattclough1
Copy link

mattclough1 commented Mar 6, 2020

just a note that this problem - #10794 (comment) was not the case in Next.js v9.0.5

To second this, I had issues polyfilling for IE11 with the with-polyfills example in a completely fresh project. Here's an example: https://github.com/mattclough1/next-ie11-polyfill-test

I also attempted to upgrade to next@canary, which had the same result, but it seems like the polyfilling approach may be different for that version.

I was able to make it work by downgrading to v9.0.8

@timneutkens
Copy link
Member

timneutkens commented Mar 7, 2020

None of the polyfills outlined here: https://github.com/mattclough1/next-ie11-polyfill-test/blob/master/client/polyfills.js

are needed if you upgrade to next@canary, Next.js will correctly provide them (and every other polyfill needed for IE11).

@mattclough1
Copy link

@timneutkens Hey Tim, I just updated the example by removing next config and polyfills script, and updating to next@canary and I'm getting the same result in IE11.

@bryanterrell
Copy link

@timneutkens, I also tried @mattclough1's repo with v9.3.0 and got the same result.

@DavydenkovM
Copy link

DavydenkovM commented Jun 2, 2020

@mattclough1 same here. with-polyfills example approach isn't working anymore. Tested on v9.4. (we're using client/polyfills.js not only for IE11, but also for critical-css https://github.com/dotsunited/load-css-polyfill)

@Timer
Copy link
Member

Timer commented Sep 12, 2020

Closing this issue as it's no longer relevant for a Next.js 9.3+ world and our docs now explain how to polyfill with a warning for this added to with-polyfills.

@Timer Timer closed this as completed Sep 12, 2020
@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants