2

I have a React application written in Typescript with Babel and Webpack. It loads fine in Firefox and Chrome, but loads a blank page in Internet Explorer 11. I am new to this project with relatively low experience with React/Babel/WebPack/Typescript. I need to make the app work with IE11. I've spent a couple days learning about what I'm working with and trying different approaches that I've found on the web, but have not found a solution yet. Based on what I am working with that I have posted below, I'm hoping this fine community can help me find a solution to get this loading in IE11. I need to get this working in prod, but development is less of a concern.

Relevant stuff from package.json

.
.
  "scripts": {
    "build": "eslint './**' && npm run clean-dist && webpack -p --config=configs/webpack/prod.js",
    "clean-dist": "rm -f -r -d dist",
    "lint": "eslint './**'",
    "start": "npm run start-dev",
    "start-dev": "webpack-dev-server --config=configs/webpack/dev.js",
    "test": "jest --watch --coverage --config=configs/jest.json",
    "prettier": "prettier 'src/**/*.{ts,tsx}' --check",
    "prettier:fix": "prettier 'src/**/*.{ts,tsx}' --write",
    "createVersionFile": "node ./bin/createVersionFile.js"
  },
  .
  .
  "devDependencies": {
    "@babel/cli": "^7.2.3",
    "@babel/core": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    .
    .
    "@types/node": "^11.9.6",
    "@types/react": "^16.9.35",
    "@types/react-dom": "^16.9.8",
    "@types/react-intl": "^2.3.17",
    "@types/react-redux": "^7.1.9",
    "@types/react-router": "^5.1.7",
    "@types/react-router-dom": "^5.1.5",
    "@types/react-test-renderer": "^16.9.1",
    .
    .
    "babel-jest": "^24.1.0",
    "babel-loader": "^8.0.5",
    "babel-plugin-react-intl": "^3.0.1",
    "copy-webpack-plugin": "^5.1.1",
    .
    .
    "webpack-cli": "^3.2.3",
    "webpack-dev-middleware": "^3.6.0",
    "webpack-dev-server": "^3.2.1",
    "webpack-merge": "^4.2.1"
  },
    dependencies": {
    "babel-plugin-transform-regenerator": "^6.26.0",
    "babel-polyfill": "^6.26.0",
    .
    .
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-dropzone": "^11.0.3",
    "react-intl": "^2.8.0",
    "react-redux": "^7.2.0",
    "react-router-dom": "^5.2.0",
  }

.bablerc

{
  "presets": [
    ["@babel/preset-env", {"modules": false}],
    "@babel/preset-react"
  ],
  "plugins": ["react-hot-loader/babel", "transform-regenerator"],
  "env": {
    "production": {
      "presets": ["minify"]
    },
    "test": {
      "presets": ["@babel/preset-env", "@babel/preset-react"]
    }
  }
}

tsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "outDir": "./dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "noImplicitThis": true,
    "alwaysStrict": true,
    "strictNullChecks": true,
    "strict": true,
    "suppressImplicitAnyIndexErrors": true,
    "module": "commonjs",
    "target": "es6",
    "jsx": "react",
    "lib": [
      "es5",
      "es6",
      "es2019",
      "dom"
    ],
    "baseUrl": "./",
    "paths": {
      "*" : ["src/@types/*"]
    },
    "resolveJsonModule": true,
    "esModuleInterop": true
  },
  "include": [
    "./src/**/*",
    "./tests/*"
  ],
  "awesomeTypescriptLoaderOptions": {
    "reportFiles": [
      "./src/**/*"
    ]
  },
  "exclude": [
    "node_modules"
  ]
}

We have separate Webpack configs for prod and dev. They both import some common configurations. This is the relevant part of the common config used by both prod and dev Webpack configs:

// shared config (dev and prod)
const {resolve} = require('path');
const {CheckerPlugin} = require('awesome-typescript-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Dotenv = require('dotenv-webpack');

module.exports = {
    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },
    context: resolve(__dirname, '../../src'),
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['babel-loader', 'source-map-loader'],
                exclude: /node_modules/,
            },
            {
                test: /\.tsx?$/,
                use: ['babel-loader', 'awesome-typescript-loader'],
            },
            .
            .

        ],
    },
    .
    .
};

Dev specific Webpack config:

const merge = require('webpack-merge');
const webpack = require('webpack');
const commonConfig = require('./common');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = merge(commonConfig, {
  mode: 'development',
  entry: [
    'react-hot-loader/patch', // activate HMR for React
    'webpack-dev-server/client?http://localhost:8081',// bundle the client for webpack-dev-server and connect to the provided endpoint
    'webpack/hot/only-dev-server', // bundle the client for hot reloading, only- means to only hot reload for successful updates
    'babel-polyfill',
    './index.tsx' // the entry point of our app
  ],
  output: {
    publicPath: '/iq-customize'
  },
  devServer: {
    //historyApiFallback: true,
    //contentBase: './',
    hot: true, // enable HMR on the server
    port: 8081
  },
  devtool: 'cheap-module-eval-source-map',
  plugins: [
    new webpack.HotModuleReplacementPlugin(), // enable HMR globally
    new webpack.NamedModulesPlugin(), // prints more readable module names in the browser console on HMR updates
    new CopyWebpackPlugin([
      { from: '../public', to: 'public' },
    ]),
  ],
});

Prod specific Webpack config:

const merge = require('webpack-merge');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const {resolve} = require('path');

const commonConfig = require('./common');

module.exports = merge(commonConfig, {
  mode: 'production',
  entry: './index.tsx',
  output: {
    filename: 'js/bundle.[hash].min.js',
    path: resolve(__dirname, '../../dist'),
    publicPath: '/iq-customize/',
  },
  devtool: 'source-map',
  plugins: [
    new CopyWebpackPlugin([
      { from: '../public', to: 'public' },
    ]),
  ],
});

index.tsx

import "babel-polyfill";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import DateFnsUtils from "@date-io/date-fns";
import { MuiPickersUtilsProvider } from "@material-ui/pickers";
import registerServiceWorker from "./registerServiceWorker";
import { ThemeProvider } from "@material-ui/core";

import App from "./App";
import store from "./modules/shared/store/store";
import { theme } from "./modules/shared/common/Theme";

const app = (
    <Provider store={store}>
        <BrowserRouter basename="/xxxxx">
            <MuiPickersUtilsProvider utils={DateFnsUtils}>
                <ThemeProvider theme={theme}>
                    <App />
                </ThemeProvider>
            </MuiPickersUtilsProvider>
        </BrowserRouter>
    </Provider>
);

ReactDOM.render(app, document.getElementById("root") || document.createElement("div"));
registerServiceWorker();
Neil Davis
  • 31
  • 4
  • Which webpack version do you have? webpack 4 or 5? And what error do you have under IE 11? – Sam Chen Nov 21 '20 at 01:50
  • The error in IE is SCRIPT1010: Expected identifier. Looks like we have Webpack 4. Here are all the webpack related dependencies from package.json: ` "dotenv-webpack": "^1.7.0", "html-webpack-plugin": "^3.2.0", "image-webpack-loader": "^4.6.0", "uglifyjs-webpack-plugin": "^2.1.2", "webpack": "^4.29.6", "webpack-cli": "^3.2.3", "webpack-dev-middleware": "^3.6.0", "webpack-dev-server": "^3.2.1", "webpack-merge": "^4.2.1" ` – Neil Davis Nov 21 '20 at 05:28
  • In your React app, in the `src` folder you will find the `index.js` file. I suggest add these 2 lines at the top. `import 'react-app-polyfill/ie11'; import 'react-app-polyfill/stable';` After that, open the `package.json` file. Add `"ie 11"` in the `development` and `production` part. Then try to delete the `.cache` folder under `node_modules` and again try to run the app. See if get load. Try to launch in both `development` and `production`. – Deepak-MSFT Nov 23 '20 at 05:58
  • @Deepak-MSFT this application is in typescript, so we don't have index.js, we have index.tsx. I have tried react-app-polyfill, but it didn't get the app working.Not sure what you mean by development and production part of package.json. – Neil Davis Nov 24 '20 at 18:13
  • @chenxsan does the SCRIPT1010 error and other details above give you any ideas? – Neil Davis Nov 24 '20 at 18:14
  • No, it's too ambiguous, would be great if you can use the debugger in IE 11 to trace the exact code causing that error, otherwise it's difficult to guess why. BTW, uglifyjs-webpack-plugin was deprecated in favor of terser-webpack-plugin for quite a long time. – Sam Chen Nov 25 '20 at 00:44
  • Please try to check, after adding the suggested polyfills for the IE browser, does error got solved, or do you see any new errors? If you are still getting the same error then I suggest you click on the error message, it will take you to the problematic line. Check in which file this error occurs and post the problematic line of code here. It may give some idea about the issue. – Deepak-MSFT Nov 26 '20 at 09:17

1 Answers1

0

Please try this, I struggled significantly trying to follow the convoluted docs and apis from all of the version changes & deprecations:

How to create IE11 Bundles with Webpack 5 and Babel 7

anthumchris
  • 8,245
  • 2
  • 28
  • 53