阅读本文你需要了解(pre-knowledge)

  1. typescript语言
  2. webpack基础知识
  3. react基础知识

如有需要, 可以阅读上一篇文章《手动创建react项目》.

简述

前几天准备整理一个dvajs + antd的项目demo. 写到组件的propTypes的时候, 就有点崩溃了, 这么反人类的类型声明实在有点难受, 于是准备再一次走上ts的不归路. 不过配置react的ts环境还是费了不少功夫. 一步一步来, 先不管dvajs和antd, 把纯react的ts环境先搭建好吧.

使用typescript

以上一篇文章留下的项目为基础, 我们把他改造成typescript版本.

  1. 首先, 当然要安装一下依赖, 我们要用到ts-loadertypescript两个包.
    npm install --save-dev ts-loader typescript
    
    • ts-loader跟之前用到的css-loader类似, 专门用来处理ts文件
    • ts-loader是依赖typescript包的, 这个就不用多说了吧.
  2. 然后用ts的语法重写index.js(文件后缀也改成ts或者tsx).

     // src/index.tsx
     import React from 'react';
     import ReactDOM from 'react-dom';
     // 这里其实可以省略string的类型声明, 不过为了测试ts的编译, 在这里加上了.
     const title: string = 'React Webpack Babel Setup Complete!';
    
     ReactDOM.render(
         <div>{title}</div>,
         document.getElementById('app')
     );
    
    

    如果看到IDE提示找不到reactreact-dom两个package的声明文件, 安装一下即可.

     npm install --save-dev @types/react @types/react-dom
    
  3. 修改webpack的配置, 在rules配置节中加上ts(x)的规则, 然后把ts(x)加入到需要解析的列表中.

     ...
     entry: [
         './src/index.tsx' // 修改入口文件
     ],
     ... // other configs
     rules: [
         ... // other rules
             {
                 test: /\.tsx?$/,
                 exclude: /node_modules/,
                 loader: 'babel-loader!ts-loader'
             },
         ]
     ...
     resolve: {
         extensions: ['*', '.js', '.jsx', '.ts' ,'.tsx']
     },
    
    • 注意在配置的loader中, 用到了babel-loader!ts-loader(这里的!类似于pipeline, 意思是先经过ts-loader的处理, 再将结果交给babel-loader处理). 因为ts-loader只负责将typescript的代码转译为javascript代码, 后面的操作还要交给babel-loader来进行.
    • 还有一点就是我们在extensions列表中加入了.ts.tsx两项, 而不是替换掉.js.jsx. 这是因为在我们引用的第三方包中, 也会有一些用js编写的代码需要webpack去解析和编译. 所以可不能把之前配置的js(x)的loader给删除哦.
  4. 接下来我们还需要在项目根目录下创建一个tsconfig.json文件, 熟悉typescript的同学应该知道, ts的配置项是非常多的, 这里我们只取需要的来配置.
     {
         "compilerOptions": {
             "jsx": "react",
             "lib": [
                 "es6",
                 "dom"
             ],
             "rootDir": "src",
             "module": "commonjs",
             "target": "es6",
             "sourceMap": true,
             "moduleResolution": "node",
             "noImplicitReturns": true,
             "noImplicitThis": true,
             "noImplicitAny": true,
             "strictNullChecks": true,
             "allowSyntheticDefaultImports": true,
             "experimentalDecorators": true,
         },
         "include": [
             "./src"
         ],
         "exclude": [
             "node_modules"
         ]
     }
    

    这些配置项的含义已经超出了今天论述的范围, 有兴趣的同学可以前往typescript官方文档了解.

  5. 到这里, 我们运行npm start已经能够成功地编译项目了, 但是打开浏览器却发现控制台报错了.
    Uncaught TypeError: Cannot read property 'render' of undefined
     at eval (index.tsx:12)
     at Object../src/index.tsx (bundle.js:1234)
     at __webpack_require__ (bundle.js:725)
     at fn (bundle.js:102)
     at eval (webpack:///multi_(:8080/webpack)-dev-server/client?:3:18)
     at Object.0 (bundle.js:1245)
     at __webpack_require__ (bundle.js:725)
     at bundle.js:792
     at bundle.js:795
    

    这应该是一个代码问题了, 回去src/index.tsx文件里看一下, 想起来ts的import和es6的不太一样, 这里要写成import * as React from 'react'才行.
    改完之后, 刷新浏览器就可以看到React Webpack Babel Setup Complete!啦.

总结

到这里, 使用typescript搭建一个简单的react开发环境就已经完成了, 当然要用ts来完整地开发一个项目肯定还不够, 后面还有很多坑等着我们去踩.
下一次我将会尝试搭建一个dvajs + antd的ts环境, 应该会包括以下内容:

  • 使用antd
  • IconFont实践
  • css模块化
  • 动态加载js模块
  • tslint和git precommit
  • 多语言支持(i18n)
  • 服务端渲染
  • 完成一个内容管理系统