How to polyfill IE11 in NextJS project?

NooNoo picture NooNoo · Oct 9, 2019 · Viewed 8.9k times · Source

I'm trying to polyfill the project for IE11 but no matter what I do browser logs these errors:

Dev mode:

SCRIPT1002: Syntax error in _app.js (49004,30)

49004 const Component = props => (react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_injectIntl__WEBPACK_IMPORTED_MODULE_2__["Context"].Consumer, null, intl => {
        Object(_utils__WEBPACK_IMPORTED_MODULE_1__["invariantIntlContext"])(intl);
        const formattedValue = intl[name](props.value, props);
        if (typeof props.children === 'function') {
            return props.children(formattedValue);
        }
        const Text = intl.textComponent || react__WEBPACK_IMPORTED_MODULE_0__["Fragment"];
        return react__WEBPACK_IMPORTED_MODULE_0__["createElement"](Text, null, formattedValue);
    }));

Build mode:

SCRIPT1006: Expected ')'

...function G(e,t,n={})

NextJS doc says that framework polyfills code from the box but it'not enought. What is missing then?


Project files:

.babelrc

{
  "env": {
    "development": {
      "plugins": [
        [
          "react-intl",
          {
            "messagesDir": "./lang/.messages/"
          }
        ]
      ],
      "presets": [
        [
          "next/babel",
          {
            "@babel/preset-env": {
              "useBuiltIns": "usage",
              "corejs": { "version": 3, "proposals": true }
            }
          }
        ]
      ]
    },
    "production": {
      "plugins": [
        [
          "react-intl",
          {
            "messagesDir": "./lang/.messages/"
          }
        ]
      ],
      "presets": [
        [
          "next/babel",
          {
            "@babel/preset-env": {
              "useBuiltIns": "usage",
              "corejs": { "version": 3, "proposals": true }
            }
          }
        ]
      ]
    },
    "test": {
      "presets": [
        [
          "next/babel",
          {
            "preset-env": {
              "modules": "commonjs"
            }
          }
        ]
      ]
    }
  },
  "presets": ["@zeit/next-typescript/babel"],
  "plugins": [["styled-components", { "ssr": true }]]
}

package.json

{
  "version": "0.1.0",
  "scripts": {
    "build": "yarn generate && yarn type-check && cross-env NODE_CONFIG_DIR=./root/etc next build ./src && yarn l10n",
    "build-storybook": "build-storybook -s ./src/static-storybook",
    "dev": "yarn generate && cross-env NODE_CONFIG_DIR=./root/etc nodemon",
    "generate": "yarn generate:clean && graphql-codegen --config codegen.server.yml && graphql-codegen --config codegen.yml && apollo client:codegen --globalTypesFile=./src/__generated__/globalTypes.ts --addTypename --target=typescript --localSchemaFile=./src/schema/__generated__/schema.graphql --includes=\"./src/{components/**/*.{ts,tsx},schema/**/*.ts,queries/**/*.ts}\" --passthroughCustomScalars --tagName gql",
    "generate:clean": "find . | grep -E \"__generated__\" | xargs rm -rf",
    "l10n": "node ./root/bin/l10n/prepare-lang.js && node ./root/bin/l10n/push.js && node ./root/bin/l10n/pull.js",
    "l10n:clean": "rm -rf lang/ node_modules/.cache/",
    "lint:styles": "stylelint \"./src/**/*.ts\" \"./src/**/*.tsx\"",
    "lint:ts": "eslint --ext .tsx,.ts src/",
    "start": "cross-env NODE_ENV=stage NODE_CONFIG_DIR=./root/etc node .next/server/index.js",
    "storybook": "start-storybook -p 6006 -s ./src/static-storybook,./src/static",
    "svgr": "npx @svgr/cli -d ./src/svgr ./src/static/svgs --ext tsx",
    "test": "jest",
    "test:watch": "jest --watch",
    "type-check": "tsc && tsc --project tsconfig.server.json"
  },
  "browserslist": [
    "last 2 versions",
    "not dead",
    "IE 11"
  ],
  "dependencies": {
    "@babel/polyfill": "^7.6.0",
    "@formatjs/intl-relativetimeformat": "^2.8.2",
    "@formatjs/intl-utils": "^0.6.1",
    "@tippy.js/react": "^2.2.0",
    "@types/classnames": "^2.2.8",
    "@types/react-input-mask": "^2.0.3",
    "@types/react-select": "^3.0.4",
    "@types/react-sidebar": "^3.0.0",
    "@zeit/next-css": "^1.0.2-canary.2",
    "@zeit/next-typescript": "^1.1.1",
    "accepts": "^1.3.5",
    "apollo-boost": "^0.4.3",
    "apollo-datasource-rest": "^0.5.0",
    "apollo-link-context": "^1.0.18",
    "apollo-link-error": "^1.1.11",
    "apollo-server-express": "^2.6.7",
    "babel-polyfill": "^6.26.0",
    "classnames": "^2.2.6",
    "config": "^3.1.0",
    "cookie": "^0.3.1",
    "cookie-parser": "^1.4.4",
    "css-vars-ponyfill": "^2.0.2",
    "dataloader": "^1.4.0",
    "date-fns": "^1.30.1",
    "express": "^4.16.4",
    "final-form": "^4.18.5",
    "final-form-arrays": "^3.0.1",
    "format-string-by-pattern": "^1.1.1",
    "glob": "^7.1.4",
    "graphql": "^14.5.6",
    "graphql-tools": "^4.0.4",
    "http-proxy-middleware": "^0.19.1",
    "intl": "^1.2.5",
    "intl-pluralrules": "^1.0.3",
    "is-valid-date": "^0.0.1",
    "isomorphic-unfetch": "^3.0.0",
    "lodash.debounce": "^4.0.8",
    "lodash.sortby": "^4.7.0",
    "merge-graphql-schemas": "^1.5.8",
    "next": "^8.1.0",
    "next-compose-plugins": "^2.2.0",
    "postcss-custom-properties": "^8.0.10",
    "postcss-nested": "^4.1.2",
    "qs": "^6.7.0",
    "react": "^16.8.6",
    "react-apollo": "^2.5.8",
    "react-components": "",
    "react-dom": "^16.8.6",
    "react-final-form": "^6.3.0",
    "react-final-form-arrays": "^3.1.1",
    "react-final-form-listeners": "^1.0.2",
    "react-input-mask": "^2.0.4",
    "react-intl": "^3.1.13",
    "react-markdown": "^4.2.2",
    "react-modal": "^3.9.1",
    "react-range": "^1.0.6",
    "react-redux": "^7.1.1",
    "react-select": "^3.0.4",
    "react-sidebar": "^3.0.2",
    "react-tooltip-lite": "^1.10.0",
    "redux": "^4.0.4",
    "redux-thunk": "^2.3.0",
    "request": "^2.88.0",
    "request-promise": "^4.2.4",
    "smoothscroll-polyfill": "^0.4.4",
    "styled-components": "^4.2.0",
    "uuid": "^3.3.2"
  },
  "devDependencies": {
    "@babel/preset-env": "^7.6.3",
    "@graphql-codegen/cli": "^1.2.0",
    "@graphql-codegen/fragment-matcher": "^1.2.0",
    "@graphql-codegen/schema-ast": "^1.2.0",
    "@graphql-codegen/typescript": "^1.2.0",
    "@graphql-codegen/typescript-operations": "^1.2.0",
    "@graphql-codegen/typescript-react-apollo": "^1.2.0",
    "@graphql-codegen/typescript-resolvers": "^1.2.0",
    "@storybook/addon-actions": "^5.1.9",
    "@storybook/addon-backgrounds": "^5.1.9",
    "@storybook/addon-info": "^5.1.9",
    "@storybook/addon-knobs": "^5.1.9",
    "@storybook/addon-links": "^5.1.9",
    "@storybook/addon-storysource": "^5.1.9",
    "@storybook/addon-viewport": "^5.1.9",
    "@storybook/addons": "^5.1.9",
    "@storybook/react": "^5.1.9",
    "@svgr/cli": "^4.2.0",
    "@types/accepts": "^1.3.5",
    "@types/config": "^0.0.34",
    "@types/cookie": "^0.3.2",
    "@types/cookie-parser": "^1.4.1",
    "@types/enzyme": "^3.9.1",
    "@types/express": "^4.16.1",
    "@types/glob": "^7.1.1",
    "@types/graphql": "^14.0.7",
    "@types/http-proxy-middleware": "^0.19.2",
    "@types/intl": "^1.2.0",
    "@types/jest": "^24.0.11",
    "@types/lodash.debounce": "^4.0.6",
    "@types/next": "^8.0.6",
    "@types/qs": "^6.5.2",
    "@types/react": "^16.8.23",
    "@types/react-dom": "^16.8.4",
    "@types/react-modal": "^3.8.2",
    "@types/request-promise": "^4.1.44",
    "@types/smoothscroll-polyfill": "^0.3.1",
    "@types/storybook__addon-actions": "^3.4.3",
    "@types/storybook__addon-info": "^4.1.2",
    "@types/storybook__addon-knobs": "^5.0.1",
    "@types/storybook__addon-links": "^3.3.5",
    "@types/storybook__react": "^4.0.2",
    "@types/styled-components": "^4.1.12",
    "@types/uuid": "^3.4.4",
    "@typescript-eslint/eslint-plugin": "^1.5.0",
    "@typescript-eslint/parser": "^1.5.0",
    "apollo": "^2.18.3",
    "awesome-typescript-loader": "^5.2.1",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^24.7.1",
    "babel-loader": "^8.0.5",
    "babel-plugin-react-intl": "^4.1.14",
    "core-js": "^3.2.1",
    "cross-env": "^6.0.3",
    "csvtojson": "^2.0.8",
    "enzyme": "^3.9.0",
    "enzyme-adapter-react-16": "^1.11.2",
    "eslint": "5.3.0",
    "eslint-config-airbnb": "17.1.0",
    "eslint-config-prettier": "^4.1.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-jsx-a11y": "^6.1.1",
    "eslint-plugin-prettier": "^3.0.1",
    "eslint-plugin-react": "^7.11.0",
    "eslint-plugin-react-hooks": "^1.6.0",
    "file-loader": "^4.2.0",
    "graphql-tag": "^2.10.1",
    "husky": "^1.3.1",
    "jest": "^24.5.0",
    "jest-dom": "^3.1.3",
    "l10n-node-client": "",
    "lint-staged": "^8.1.5",
    "nodemon": "^1.18.10",
    "prettier": "^1.16.4",
    "react-addons-test-utils": "^15.6.2",
    "react-docgen-typescript-loader": "^3.1.0",
    "react-testing-library": "^6.0.3",
    "storybook-addon-intl": "^2.4.1",
    "storybook-addon-styled-component-theme": "^1.2.1",
    "stylelint": "^10.0.1",
    "stylelint-config-recommended": "^2.2.0",
    "stylelint-config-styled-components": "^0.1.1",
    "stylelint-processor-styled-components": "^1.6.0",
    "ts-node": "^8.0.3",
    "typescript": "^3.6.3"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged && tsc"
    }
  }
}

polyfills.js

import 'babel-polyfill';

import cssVarsPonyfill from 'css-vars-ponyfill';

if (!('remove' in Element.prototype)) {
  Element.prototype.remove = function() {
    if (this.parentNode) {
      this.parentNode.removeChild(this);
    }
  };
}

cssVarsPonyfill({
  onlyLegacy: true,
  exclude: '[data-styled]',
});

next.config.js

const { PHASE_PRODUCTION_BUILD } = require('next-server/constants');
const withPlugins = require('next-compose-plugins');
const typescript = require('@zeit/next-typescript');
const css = require('@zeit/next-css');
const getLocalIdent = require('css-loader/lib/getLocalIdent');
const config = require('config');

module.exports = withPlugins([typescript, css], {
  distDir: '../.next',
  assetPrefix: config.get('development') ? '' : '/avia',
  cssModules: true,
  cssLoaderOptions: {
    importLoaders: 1,
    localIdentName: '[local]___[hash:base64:5]',
    camelCase: true,
    getLocalIdent: (loaderContext, localIdentName, localName, options) => {
      // FIXME Костыль для импорта css-файлов из react-components без преобразования имен классов
      if (loaderContext.resourceQuery === '?raw-class-name') {
        return localName;
      }

      return getLocalIdent(loaderContext, localIdentName, localName, options);
    },
  },
  [PHASE_PRODUCTION_BUILD]: {
    cssLoaderOptions: {
      importLoaders: 1,
      localIdentName: '[local]___[hash:base64:5]',
      camelCase: true,
      getLocalIdent: (loaderContext, localIdentName, localName, options) => {
        // FIXME Костыль для импорта css-файлов из react-components без преобразования имен классов
        if (loaderContext.resourceQuery === '?raw-class-name') {
          return localName;
        }

        return getLocalIdent(loaderContext, localIdentName, localName, options);
      },
    },
  },
  webpack(config) {
    const originalEntry = config.entry;

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

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

      return entries;
    };

    config.module.rules.push({
      test: /\.(graphql|gql)$/,
      exclude: /node_modules/,
      loader: 'graphql-tag/loader',
    });

    config.module.rules.push({
      test: /\.(png|svg|jpg|gif)$/,
      use: [
        {
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]',
          },
        }
      ]
    });

    config.stats = {
      // https://github.com/webpack-contrib/mini-css-extract-plugin/issues/250
      warningsFilter: (warning) => /Conflicting order between/m.test(warning),
    };

    return config;
  },
});

Answer