将 React ES6 迁移到 TypeScript:import 语句不起作用

Posted

技术标签:

【中文标题】将 React ES6 迁移到 TypeScript:import 语句不起作用【英文标题】:Migrating React ES6 to TypeScript: import statements don't work 【发布时间】:2016-02-21 00:06:10 【问题描述】:

我目前有一个用 ES6 编写的 React 项目,我正在迁移到 TypeScript。我在使用 import 语句时遇到问题。

目前使用 ES6,我使用 NPM 安装了 React 依赖项,例如 npm install react,并使用 Babel 和 Browserify 来构建输出 ES5 包。 (使用 Browserify 不是必需的,我只是想让 TS 与该项目一起工作。)

一个典型的 React ES6 文件如下所示:

import React from "react"
import Router, Route, Link from "react-router"
import Button from "./components/Button"

export default class App extends React.Component 
    render() 
        // ...
    

进入 TS,我使用 tsd install react/ 为我的所有 React 依赖项安装了 d.ts 文件,设置 TSC module: "commonjs"jsx: "react",将一些文件从 *.jsx 转换为 *.tsx,然后我在import 语句中得到这些编译错误:

错误:(1, 8) TS1192:模块“react”没有默认导出。

import Button 语句没有错误。似乎 TSC 无法解决 NPM 模块依赖关系。

我怎样才能让它工作?

【问题讨论】:

我正面临另一个问题。我有一个用 TypeScript 构建的库。我构建了它并尝试导入 js 文件。 localhost:3000 对我来说效果很好。但是当我做npm run build 时,它说 ts-file-transpiled.js 有 someFunc() 没有正确导出。我不知道该怎么做。 【参考方案1】:

TypeScript 1.8+

使用--allowSyntheticDefaultImports 编译——将"allowSyntheticDefaultImports": true 添加到tsconfig.json

注意:tsconfig.json 中的 module 设置为 commonjs 时,这对我不起作用。

或者...

改用这个:

import * as React from "react";
import * as Router from "react-router";

// use React, Router.Router, Router.Route, and Router.Link here

阅读更多 here 和 here。目前react.d.ts使用export =,所以你需要通过import * as React来导入。

基本上这些库只有一个导出。这在定义文件中以export = 表示。

【讨论】:

谢谢,确实有效。区别是什么仍然有点模糊。 Router, Route, Link from 'react-router' 呢?有没有办法做到这一点? 已接受。 :) 仍然有点困惑,但是...所以需要* as 的原因是因为d.ts 使用export =,但我认为这相当于ES6 export default,它将使用import React from 'react' 导入?我不清楚为什么它与 Babel/Browserify 一起工作,但语义似乎随着 TSC 发生了变化。我猜它在模块的解析方式上有所不同? 我也不确定ReactRouter.Router 语法。现有的 JS 代码作为 Router 工作,那么 import * as ReactRouter 在运行时如何工作? 查看 Babel 转译的代码,我看到我所有的默认导入 (import React from 'react') 都使用 react2 = _interopRequireDefaultExport(react) 检查 __esModule 并做了一些我不完全理解的转换,然后我的代码通过转换后的 react2 变量引用 React。我在 TSC 转译的代码中看不到任何类似的东西。我猜这就是区别。我的头在旋转。 :) 啊哈!我发现我可以做到import Router from 'react-router/lib/Router'。这对我很好。【参考方案2】:

为了使用以下语法:

import React from 'react';

你需要在tsconfig.json中设置这两个标志:

 "allowSyntheticDefaultImports": true, "esModuleInterop": true 

使用以下版本进行测试: 打字稿 2.9.2 @types/react 16.4.7 反应 16.4.1

【讨论】:

以上是关于将 React ES6 迁移到 TypeScript:import 语句不起作用的主要内容,如果未能解决你的问题,请参考以下文章

从 React 到 Preact 迁移指南

将 Node.js 项目从普通 ES6 迁移到 TypeScript

Webpack Error React & ES6 之前在 Babelify 下工作

迁移到Webpack / ES6 - 依赖注入失败

将 create-react-app 从 javascript 迁移到 typescript

将函数绑定到组件 React es6 的不同方法是啥 [重复]