TypeScript+webpack4+react实践
2019-07-25 本文已影响0人
tracyXia
一、相关环境搭建
1.安装typescript以及用到的第三方库的声明文件
npm install --save typescript @types/node @types/react @types/react-dom @types/jest @types/react-router-dom
2.针对ts、tsx文件我们需要通过babel-loade以及ts-loader编译
npm install babel-loader ts-loader --save -dev
ts-loader可以让Webpack使用TypeScript的标准配置文件tsconfig.json编译TypeScript代码。
如果webpack为4.x以下版本,ts-loader只能安装3.x版本,因为更高版本的ts-loade仅支持webpack4.x版本
npm install ts-loader@3
webpack.config.js文件添加配置如下内容:
module: {
rules: [
{
test: /\.tsx?$/,
use: ['babel-loader', 'ts-loader'],
exclude: /node_modules/,
} ]
},
resolve:{
extensions: ['.js', '.jsx','.tsx', '.ts'] //引入文件时无需加以上后缀
}
在低版本webpack中进行配置,若webpack运行时抛出一个错误:
TypeError: element.loader.split is not a function
原来是loader期待的一个字符串,而这里明显是一个数组,数组没有split方法:
//修改前
loaders: [
{ test: /\.(ts|tsx)$/,loader:['babel-loader', 'ts-loader'],exclude: /node_modules/}
]
//修改后
loaders: [
{ test: /\.(ts|tsx)$/,loaders:['babel-loader', 'ts-loader'],exclude: /node_modules/},
{ test: /\.(js|jsx)$/, loader: "jsx!babel", include: /src/ ,exclude: /node_modules/},
{ test: /\.css$/, loader: ExtractTextPlugin.extract("css", "css!postcss") },
{ test: /\.scss$/, loader: ExtractTextPlugin.extract("css", "css!postcss!sass!sass-resources") },
{test: /\.less$/, loader: ExtractTextPlugin.extract('css','css!postcss!less')},
{ test: /\.(png|jpg)$/, loader: 'url?limit=8192&name=images/[hash:8].[name].[ext]' }
]
3.添加TypeScript配置文件 ,在当前根目录下创建tsconfig.json文件,并添加如下内容:
{
"compilerOptions": {
"module": "esnext",
"target": "es6",
"allowSyntheticDefaultImports": true,
// import的相对起始路径
"baseUrl": ".",
"sourceMap": true,
// 构建输出目录,但因为使用了`webpack`,所以这个配置并没有什么卵用
"outDir": "../client-dist",
// 开启`JSX`模式,
// `preserve`的配置让`tsc`不会去处理它,而是使用后续的`babel-loader`进行处理
"jsx": "preserve",
"strict": true,
"moduleResolution": "node",
// 开启装饰器的使用
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
// `vs code`所需要的,在开发时找到对应的路径,真实的引用是在`webpack`中配置的`alias`
"paths": {
"@Common": [
"../src/common"
],
"@Common/*": [
"../src/common/*"
]
}
},
"exclude": [
"node_modules"
]
}
开启typescript代码校验的相关设置可以参看上篇文章
二、在React项目中使用TypeScript
在 react 中使用 ts 的几点变化
- 文件以tsx后缀命名
- 使用组件声明时的Component<P, S>泛型参数声明,来代替PropTypes
- 全局变量或者自定义的window对象属性,统一在项目根目录下的global.d.ts中进行声明定义
- 对于项目中常用到的接口数据对象,可以在types/目录下定义好其结构化类型声明
1.类组件的声明
/*定义属性props的类型 */
interface Iprops{
chooseBrandSeries:(clickBrand:string, brandText:string, clickSeries:any, seriesText:string)=>void //在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
}
/*定义状态机state的类型 */
interface Istate{
currentIndex: number, //控制品牌筛选项的选中样式
seriesIndex: number, //控制车系筛选项的选中样式
brandLists: any[], //品牌筛选项
isShow: boolean, //控制车系筛选项的展示
chexi: any[], //车系筛选项
clickBrand: string, //用于存储选中的品牌信息,如"408844",
brandText: string, //用于存储选中的品牌名
clickSeries: string, //用于存储选中的车系信息,如"409052"
seriesText: string, //用于存储选中的车系名
index: string
}
export default class ScrollList extends React.Component<Iprops,Istate> {
constructor(props:Iprops) {
super(props);
}
private loadMoreTimer:any;
state:Istate={
flag: false
}
}
有了 Typescript 之后可以安全地约束 Props 和 State, 没有必要引入 React.PropTypes, 而且它的表达能力比较弱
TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public、private 和 protected
- public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
- private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
- protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的