React 和 ReactDOM 未定义但已安装

Sha*_*ews 1 javascript reactjs

我只是想用 .tsx 转译器制作一个简单的 react 应用程序,但 react 和 react-dom 在导入时未定义:

这是我的入口文件和唯一的打字稿文件:

索引.tsx

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

console.log(ReactDOM);

ReactDOM.render(<div>SUCCESS!</div>, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)

控制台输出错误:

undefined
Uncaught TypeError: Cannot read property 'render' of undefined
Run Code Online (Sandbox Code Playgroud)

ReactDOM 对象输出为“未定义”,因此 render() 在未定义的对象上失败。使用'npm install --save-dev react react-dom'以正常方式安装了React和ReactDOM模块,并验证了node_modules下存在两个react文件夹。

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: [

  ]
};
Run Code Online (Sandbox Code Playgroud)

包.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"
  }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*lio 7

将 TypeScript 中模块的所有导出导入单个名称的正确语法是:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
Run Code Online (Sandbox Code Playgroud)

(注意* as部分)

您使用的语法将导入default导出,React 不提供 AFAIK。(因此undefined。)

这种情况有点令人困惑,因为如果没有提供导出,IIRC babel 会将整个module.exports对象公开为default导出default,但 TypeScript 不会。

PS:还要确保通过 npm安装@types/react@types/react-dom作为依赖项,以便获得完全自动完成和类型检查。


编辑 (2018-04-04): 从 TypeScript 2.7 开始,上面的答案不再完全准确。

新的--esModuleInterop编译器选项提供了更接近 Babel 和 ES6 模块规范的导入语义。

启用该选项后,TypeScript 编译器module.exports会将CommonJS映射到 ES6 default export ...,因此import foo from 'bar'现在应该可以像在 Babel 上一样正常工作。

请记住,--esModuleInterop当前默认情况下禁用它以允许更平滑的过渡,但 TypeScript 文档建议为新项目和现有项目启用它。

(您可以通过命令行或tsconfig.json文件启用它)

注意:import * as foo from 'bar'语法仍然有效,但它现在仅用于将所有非默认导出分组到单个标识符下的情况。(不常见)

有关更改及其解决的问题的更多信息,请参阅TypeScript 2.7 发行说明相关部分