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();