3

I'm just trying to make a simple react app with a .tsx transpiler, but the react and react-dom are undefined upon import:

This is my entry file and only typescript file:

index.tsx

import React from 'react';
import ReactDOM from 'react-dom';

console.log(ReactDOM);

ReactDOM.render(<div>SUCCESS!</div>, document.getElementById('root'));

Console output errors:

undefined
Uncaught TypeError: Cannot read property 'render' of undefined

The ReactDOM object is output as 'undefined' so the render() fails on undefined object. Installed the React and ReactDOM modules the normal way with 'npm install --save-dev react react-dom' and that verified both react folder exist under node_modules.

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './src/js/index.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/dist'
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx']
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  },
  plugins: [

  ]
};

package.json

{
  "name": "helloworld",
  "version": "1.0.0",
  "description": "Hello there",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack-dev-server",
    "build:prod": "webpack -p"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "awesome-typescript-loader": "^3.2.3",
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.0",
    "babel-preset-react": "^6.24.1",
    "css-loader": "^0.28.7",
    "react": "^16.0.0",
    "react-dom": "^16.0.0",
    "style-loader": "^0.19.0",
    "ts-loader": "^2.3.7",
    "typescript": "^2.5.3",
    "webpack": "^3.7.1",
    "webpack-dev-server": "^2.9.1"
  }
}
2
  • try rm -rf node_modules then npm i, check if it works Commented Oct 14, 2017 at 19:40
  • 1
    react and reactdom should not be dev dependencies... make them regular dependencies Commented Oct 14, 2017 at 19:47

2 Answers 2

10

The proper syntax for importing all the exports of a module in TypeScript into a single name is:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

(Notice the * as part)

The syntax you're using will instead import the default export, which React does not provide AFAIK. (Hence undefined.)

The situation is a bit confusing because IIRC babel will expose the whole module.exports object as the default export if no default export is provided, but TypeScript will not.

PS: Also make sure you install @types/react and @types/react-dom as dependencies via npm so you get full autocompletion and type checking.


Edit (2018-04-04): As of TypeScript 2.7, the answer above is no longer entirely accurate.

The new --esModuleInterop compiler option provides import semantics more closely aligned with Babel and with the ES6 modules spec.

With the option enabled CommonJS module.exports will be mapped to ES6 default export ... by the TypeScript compiler, so import foo from 'bar' should now work without any issues just like on Babel.

Keep in mind that --esModuleInterop is currently disabled by default to allow for a smoother transition, but the TypeScript docs recommend enabling it for both new and existing projects.

(You can enable it via the command line or via a tsconfig.json file)

Note: The import * as foo from 'bar' syntax is still valid, but it's now only used in the cases where you want to group all non-default exports under a single identifier. (Not as common)

For more info on the change and the problems it addresses, see the Relevant section of the Release Notes for TypeScript 2.7

Sign up to request clarification or add additional context in comments.

2 Comments

React does provide default export.
Solved! Thank you Marco! I didn't know TypeScript did that.
0

Faced the same issue. In my case, this happens due to upgrading only react without React dom.

For example - React: 17.x and React-DOM: 16.x

Try below command which helped to resolve this issue.

npm update react react-dom --depth 4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.