React项目从Javascript到Typescript的迁移经验总结

Godfavoredone 2019-07-01

抛转引用

现在越来越多的项目放弃了javascript,而选择拥抱了typescript,就比如我们熟知的ant-design就是其中之一。面对越来越火的typescript,我们公司今年也逐渐开始拥抱typescript。至于为什么要使用typescript?本文不做深入探讨,对这方面有兴趣的小伙伴们可以去看一下这篇文章:

TypeScript体系调研报告

这篇文章比较全面地介绍了TypeScript,并且和Javascript做了一个对比。看完上面这篇文章,你会对TypeScript有一个比较深入的认识,另外在TypeScript和Javascript的取舍上,可以拿捏得更好。

开始迁移

在开始迁移之前,我要说点题外话,本篇文章仅是记录我在迁移过程中遇到的问题以及我是如何解决的,并不会涉及typescript的教学。所以大家在阅读本篇文章之前,一定要对typescript有一个基础的认识,不然你读起来会非常费力。

环境调整

由于Typescript是Javascript的超集,它的很多语法浏览器是不能识别的,因此它不能直接运行在浏览器上,需要将其编译成JavaScript才能运行在浏览器上,这点跟ES6需要经过babel编译才能支持更多低版本的浏览器是一个道理。

tsconfig.json

首先我们得装一个typescript,这就跟我们在用babel前需要先装一个babel-core是一个道理。

yarn global add typescript

这条命令是将typescript安装在全局,其实我个人建议是装在项目目录下的,因为每个项目的typescript版本是不完全一样的,装在全局容易因为版本不同而出现问题。但是后面我要执行tsc命令,所以我装在了全局。最好的情况就是全局和项目都装一个,但是如果你把tsc命令放在package.json中的script中去用的话,那么在项目里装就够了。接下来我们执行如下命令生成tsconfig.json,这玩意就跟.babelrc是一个性质的。

tsc --init

执行完之后,你的项目根目录下便会有一个tsconfig.json这么一个东西,但是里面会有很多注释,我们先不用管他的。

webpack

安装ts-loader用于处理ts和tsx文件,类似于babel-loader。

yarn add ts-loader -D

相应的webpack需要加上ts的loader规则:

module.exports = {
    //省略部分代码...
    module: {
        rules: [
            {
                test:/\.tsx?$/,
                loader:'ts-loader'
            }
            //省略部分代码...
        ]
    }
    //...省略部分代码
}

之前用javascript的时候,可能有人不使用.jsx文件,整个项目都是用的.js文件,webapck里面甚至都不配.jsx的规则。但是在typescript项目中想要全部使用.ts文件这就行不通了,会报错,所以当用到了jsx的用法的时候,还是得乖乖用.tsx文件,因此这里我加入了.tsx的规则。

删除babel

关于babel这块,网上有不少人是选择留着的,理由很简单,说是为了防止以后会使用到JavaScript,但是我个人觉得是没有必要留着babel。因为我们整个项目里面基本上只有使用第三方包的时候才会用到javascript,而这些第三方包基本上都是已经编译成了es5的代码了,不需要babel再去处理一下。而业务逻辑里面用javascript更是不太可能了,因为这便失去了使用typescript的意义。综上所述,我个人觉得是要删除babel相关的东西,降低项目复杂度。但是有一个例外情况:。

当你用了某些babel插件,而这些插件的功能恰巧是typescript无法提供的,那你可以保留babel,并且与typescript结合。

文件名调整

整个src目下所有的.js结尾的文件都要修改文件名,使用到jsx语法的就改成.tsx文件,未使用的就改成.ts文件,这块工作量比较大,会比较头疼。另外改完之后文件肯定会有很多标红的地方,不要急着去改它,后面我们分类统一去改。

解决报错

webpack入口文件找不到

React项目从Javascript到Typescript的迁移经验总结
由于我们在做文件名调整的时候,把main.js改成main.tsx,因此webpack的入口文件要改成main.tsx。

module.exports = {
    //省略部分代码...
    entry: {
        app: './src/main.tsx'
    },
    //省略部分代码...
}

提示不能使用jsx的语法

React项目从Javascript到Typescript的迁移经验总结
这个解决很简单,去tsconfig配置一下即可。

{
   "compilerOptions":{
        "jsx": "react"
   }
}

jsx这个配置项有三个值可选择,分别是"preserve","react-native"和"react"。在preservereact-native模式下生成代码中会保留JSX以供后续的转换操作使用(比如:Babel)。另外,preserve输出文件会带有.jsx扩展名,而react-native是.js拓展名。react模式会生成React.createElement,在使用前不需要再进行转换操作了,输出文件的扩展名为.js。

模式输入输出输出文件扩展名
preserve<div /><div />.jsx
react<div />React.createElement("div").js
react-native<div /><div />.js

webpack里面配置的alias无法解析

module.exports = {
    //省略部分代码...
    resolve: {
        alias:{
          '@':path.join(__dirname,'../src')
        }
        //省略部分代码...    
    },
    //省略部分代码...   
}

React项目从Javascript到Typescript的迁移经验总结
这里需要我们额外在tsconfig.json配置一下。

{
    "compilerOptions":{
        "baseUrl": ".",
        "paths": {
          "@/*":["./src/*"]
        } 
    }
}

具体如何配置,请看typescript的文档,我就不展开介绍了,但是要注意的是baseUrl和paths一定要配合使用。

https://www.tslang.cn/docs/ha...

无法自动添加拓展名而导致找不到对应的模块

React项目从Javascript到Typescript的迁移经验总结
原先我们在webpack里是这么配置的:

module.exports = {
    //省略部分代码... 
    resolve: {
        //省略部分代码... 
        extensions: ['.js', '.jsx', '.json']
    },
    //省略部分代码... 
}

但是我们项目里所有.js和.jsx的文件都改成了.ts和.tsx文件,因此配置需要调整。

{
    //省略部分代码... 
    resolve: {
        //省略部分代码... 
        extensions: ['.ts','.tsx','.js', '.jsx', '.json']
    },
    //省略部分代码... 
}

Could not find a declaration file for module '**'

这个比较简单,它提示找不到哪个模块的声明文件,你就装个哪个模块的就好了,安装格式如下:

yarn add @types/**

举个

相关推荐