栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

TypeScript在react项目中的实践

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

TypeScript在react项目中的实践

前段时间有写过一个Typescript在node项目中的实践。
在里边有解释了为什么要使用TS,以及在Node中的一个项目结构是怎样的。
但是那仅仅是一个纯接口项目,碰巧赶上近期的另一个项目重构也由我来主持,经过上次的实践以后,尝到了TS所带来的甜头,毫不犹豫的选择用TS+React来重构这个项目。
这次的重构不仅包括Node的重构(之前是Express的项目),同时还包括前端的重构(之前是由jQuery驱动的多页应用)。

项目结构

因为目前项目是没有做前后分离的打算的(一个内部工具平台类的项目),所以大致结构就是基于上次Node项目的结构,在其之上添加了一些FrontEnd的目录结构:

  .
  ├── README.md
  ├── copy-static-assets.ts
  ├── nodemon.json
  ├── package.json
+ ├── client-dist
+ │   ├── bundle.js
+ │   ├── bundle.js.map
+ │   ├── logo.png
+ │   └── vendors.dll.js
  ├── dist
  ├── src
  │   ├── config
  │   ├── controllers
  │   ├── entity
  │   ├── models
  │   ├── middleware
  │   ├── public
  │   ├── app.ts
  │   ├── server.ts
  │   ├── types
+ │   ├── common
  │   └── utils
+ ├── client-src
+ │   ├── components
+ │   │   └── Header.tsx
+ │   ├── conf
+ │   │   └── host.ts
+ │   ├── dist
+ │   ├── utils
+ │   ├── index.ejs
+ │   ├── index.tsx
+ │   ├── webpack
+ │   ├── package.json
+ │   └── tsconfig.json
+ ├── views
+ │   └── index.ejs
  ├── tsconfig.json
  └── tslint.json

其中标绿(也可能是一个+号显示)的文件为本次新增的。
其中client-dist与views都是通过webpack生成的,实际的源码文件都在client-src下。就这个结构拆分前后分离其实没有什么成本
在下边分了大概这样的一些文件夹:

dir/file desc
index.ejs 项目的入口html文件,采用ejs作为渲染引擎
index.tsx 项目的入口js文件,后缀使用tsx,原因有二:
1. 我们会使用ts进行React程序的开发
2. .tsx文件在vs code上的icon比较好看 :p
tsconfig.json 是用于tsc编译执行的一些配置文件
components 组件存放的目录
config 各种配置项存放的位置,类似请求接口的host或者各种状态的map映射之类的(可以理解为枚举对象们都在这里)
utils 一些公共函数存放的位置,各种可复用的代码都应该放在这里
dist 各种静态资源的存放位置,图片之类文件
webpack 里边存放了各种环境的webpack脚本命令以及dll的生成
前后端复用代码的一个尝试

实际上边还漏掉了一个新增的文件夹,我们在src目录下新增了一个common目录,这个目录是存放一些公共的函数和公共的config,不同于utils或者config的是,这里的代码是前后端共享的,所以这里边的函数一定要是完全的不包含任何环境依赖,不包含任何业务逻辑的。

类似的数字千分位,日期格式化,抑或是服务监听的端口号,这些不包含任何逻辑,也对环境没有强依赖的代码,我们都可以放在这里。
这也是没有做前后分离带来的一个小甜头吧,前后可以共享一部分代码。

要实现这样的配置,基于上述项目需要修改如下几处:

  1. src下的utils和config部分代码迁移到common文件夹下,主要是用于区分是否可前后通用
  2. 为了将对之前node结构方面的影响降至最低,我们需要在common文件夹下新增一个index.ts索引文件,并在utils/index.ts下引用它,这样对于node方面使用来讲,并不需要关心这个文件是来自utils还是common
// src/common/utils/comma.ts
export default (num: number): string => String(num).replace(/B(?=(d{3})+$)/g, ',')

// src/common/utils/index.ts
export { default as comma } from './comma'

// src/utils.index.ts
export * from '../common/utils'

// src/app.ts
import { comma } from './utils' // 并不需要关心是来自common还是来自utils

console.log(comma(1234567)) // 1,234,567
  1. 然后是配置webpack的alias属性,用于webpack能够正确的找到其路径
// client-src/webpack/base.js
module.exports = {
  resolve: {
    alias: {
'@Common': path.resolve(__dirname, '../../src/common'),
    }
  }
}
  1. 同时我们还需要配置tsconfig.json用于vs code可以找到对应的目录,不然会在编辑器中提示can't find module XXX
// client-src/tsconfig.json
{
  "compilerOptions": {
    "paths": {
      // 用于引入某个`module`
      "@Common*{.js,.ts}`],
})

// 后续的逻辑就都一样了
export default app

当然,这个是新版发出以后的逻辑了,基于现有的结构也可以绕过去,但是就不能使用@Render装饰器了,抛开koa-views直接使用内部的consolidate:

// controller/index.ts
// 这个修改不需要改动`app.ts`,可以直接使用`createKoaServer`
import {
  Get,
  Controller,
} from 'routing-controllers'
import cons from 'consolidate'
import path from 'path'

@Controller()
export default class {
  @Get('/')
  async router() {
    // 直接在接口返回时获取模版渲染后的数据
    return cons.ejs(path.resolve(__dirname, '../../views/index.ejs'), {
      title: 'Example For Typescript React App',
    })
  }
}

目前的示例代码采用的上边的方案

小结

至此,一个完整的TS前后端项目架构就已经搭建完成了(剩下的任务就是往骨架里边填代码了)。
我已经更新了之前的typescript-exmaple 在里边添加了本次重构所使用的一些前端TS+React的示例,还包括针对@Render的一些兼容。

Typescript是一个很棒的想法,解决了N多javascript种令人诟病的问题。
使用静态语言来进行开发不仅能够提高开发的效率,同时还能降低错误出现的几率。
结合着强大的vs code,Enjoy it.

如果在使用TS的过程中有什么问题、或者有什么更好的想法,欢迎来沟通讨论。

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号