改建创设筑工程具及测试用例,TypeScript在react项目中的实践

By admin in 4858美高梅 on 2019年4月12日

前段时间有写过3个TypeScript在node项目中的实践。
在中间有分解了为什么要选用TS,以及在Node中的1个种类组织是哪些的。
可是那可是是三个纯接口项目,碰巧遇上近日的另二个品种重构也由本人来主持,经过上次的执行以往,尝到了TS所拉动的甜头,不加思索的选料用TS+React来重构那一个类型。
此次的重构不仅囊括Node的重构(之前是Express的项目),同时还包含前端的重构(此前是由jQuery使得的多页应用)。

Typescript简介

维基百科:
TypeScript是1种由微软支付的轻易和开源的编制程序语言。它是JavaScript的一个严刻超集,并添加了可选的静态类型和依据类的面向对象编制程序。C#的首席架构师以及Delphi和Turbo
帕斯Carl的开山Anders·Haier斯Berg加入了TypeScript的费用。Typescript是ES6的超集。添加了可选的静态类型(注意并不是强类型)和依据类的面向对象编制程序。
汉语官网:
https://wwwtslang.cn
特点:微软支付,javascript超集,服从ES陆正规,
任何js语法都得以平素在ts里编写运转。Angular二框架是用Typescript开发的,
背景是谷歌(谷歌)和微软,有非常大也许是鹏程的前端脚本语言发展的主流趋势。优点:帮忙ES陆标准,学到的typescript语法未来是客户端脚本语言的主流语法。强大的IDE扶助:
壹、类型检查。 贰、语法提醒。
三、重构(修章名称的时候会自动把引用的地点都重构)是Angular2的首要接纳开发语言。

接下去,大家要创造一个基础模版,将一切网址的框架搭出来。

近年的壹段时间一向在搞TypeScript,2个巨硬出品、赋予JavaScript言语静态类型和编写翻译的语言。
首先个完全使用TypeScript重构的纯Node.js品种已经上线并稳定运维了。
其次个左右端的项目最近也在重构中,关于前端基于webpack改建创设筑工程具及测试用例,TypeScript在react项目中的实践。的TypeScript套路此前也有提到过:TypeScript在react项目中的实践。

花色结构

因为脚下项目是从未做上下分离的打算的(二个里面工具平台类的连串),所以大约结构正是基于上次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

里头标绿(也说不定是2个+号显示)的文本为此次新增的。
其中client-distviews都是通过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的生成

环境搭建

配置模版路径

我们先是供给在manage.py所在的体系根目录下创造三个文本夹templates用于存放项目标有着模版文件,所谓模版文件,其实正是一对足以利用Django特点模版语法的html文件。

模版文件夹路径

创制好这么些文件夹后,我们要求再打开settings.py文件,配置那一个模版文件的门路,那样项目才能找到模版文件的职分。在settings.py中找到TEMPLATES那项,将’DILANDS’里的始末改成如下所示:

templates

其中的BASE_DI奥迪Q5是settings.py前几行预先安装的连串根目录地点,那样填写就也就是将项目模版文件的职分指向根目录下的templates文件夹。

同理,大家也亟需经过平等的布局让项目知晓静态文件的途径。

只是那个做完之后也总感觉到缺了一定量什么 (没有尽兴)

前后端复用代码的1个尝试

实则边还漏掉了3个激增的文本夹,大家在src目录下增加产量了三个common目录,那么些目录是存放在1些共用的函数和公共的config,不同于utils或者config的是,那里的代码是前后端共享的,所以那里边的函数一定借使完全的不带有其余条件重视,不含有别的工作逻辑的。

恍如的数字千分位,日期格式化,抑或是劳务监听的端口号,这几个不包括别的逻辑,也对环境未有强依赖的代码,大家都得以放在此处。
那也是不曾做上下分离带来的一个小甜头吧,前后能够共享壹部分代码。

要落到实处如此的安顿,基于上述项目要求修改如下几处:

  1. src下的utilsconfig部分代码迁移到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. 接下来是安顿webpackalias属性,用于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/*": [
        "../src/common/*"
      ]
    }
  }
}
  1. 最后在client-src/utils/index.ts写上类似server端的处理就足以了

// client-src/utils/index.ts
export * from '@Common/utils'

// client-src/index.tsx
import { comma } from './utils'

console.log(comma(1234567)) // 1,234,567

在线环境:

http://www.typescriptlang.org/play/index.html

布署静态文件路径

大家在settings.py中能找到一个STATIC_U翼虎L变量,那个变量用于钦定templates调用静态文件时的引用根目录,不过项目仍不清楚存放静态文件的根路径在哪,那里供给大家写入3个变量STATICFILES_DIKoleosS实行点名。

静态文件路径

4858美高梅 1
科学,照旧有陆分之一的JavaScript代码存在于项目中,作为1个TypeScript的言传身教项目,表现的很不纯粹。
故此有未有一点都不小概率将那么些JavaScript代码也换来TypeScript呢?
答案肯定是局地,首先须求分析那么些代码都以怎么:

环境的搭建

设若应用vs code拓展支付,而且使用了ESLint的话,要求修改TS语法援救的后缀,添加typescriptreact的某些拍卖,那样才会活动修复一些ESLint的规则:

"eslint.validate": [
  "javascript",
  "javascriptreact",
  {
    "language": "typescript",
    "autoFix": true
  },
  {
    "language": "typescriptreact",
    "autoFix": true
  }
]

4858美高梅,当土人参境:

我们那里推荐应用vscode编辑器,因为作者其就是采纳typescript开发,所以对此语言的协助很好。而且全体丰盛的插件生态系统,五个月前刚知道vscode的时候,那时感觉插件还并未有那么多,以往重新看了弹指间,真是应有尽有。牛逼啊!大文件秒开,是三个轻量且强大的代码编辑器。

此处大家来证实一下Django配置文件中多少个与静态文件有关的目录的意义:

STATIC_UKugaL是停放静态文件的地点,Django会私下认可在那边找到静态文件,不过我们一般不会在1起来就把静态文件放进去,因为最终在联合发表前需求从各文件夹收集静态文件放到那里,有相当大可能覆盖原来的书文件。

STATIC_ROOT是静态文件相对于系统的目录。

MEDIA_U逍客L一般会将上传的文书放入那么些文件夹。

MEDIA_ROOT同STATIC_ROOT。

STATICFILES_DI奥迪Q3S二个元组,里面放置开发时静态文件自动搜索的目录,大家在支付是先建贰个common_static即公用的静态文件夹,在里面放大家相濡以沫的静态文件,等最终动用静态文件收集命令一并处理。

  • Webpack打包时的布署文件
  • 部分粗略的测试用例(使用的mocha和chai)

webpack的配置

因为在前端采取了React,依据最近的主流,webpack必然是须要的。
并从未采纳成熟的cra(create-react-app)来开始展览环境搭建,原因有下:

  1. webpack履新到4后头并从未品味过,想本人耍1耍
  2. 结合着TS以及商店内部的东西,会有部分自定义配置情形的面世,担心一回开发太繁琐

不过实际上也从不太多的安顿,此次重构选拔的UI框架为谷歌(Google)Material的落到实处:material-ui
而他们选取的是jss
来开始展览体制的编纂,所以也不会波及到事先惯用的scss的那1套loader了。

webpack分了大约如下多少个文件:

file desc
common.js 公共的webpack配置,类似env之类的选项
dll.js 用于将一些不会修改的第三方库进行提前打包,加快开发时编译效率
base.js 可以理解为是webpack的基础配置文件,通用的loader以及plugins在这里
pro.js 生产环境的特殊配置(代码压缩、资源上传)
dev.js 开发环境的特殊配置(source-map

dll是3个很早在此之前的老路了,大致要求修改这么几处:

  1. 创设二个独门的webpack文本,用于转移dll文件
  2. 在平凡的webpack文件中开展引用生成的dll文件

// dll.js
{
  entry: {
    // 需要提前打包的库
    vendors: [
      'react',
      'react-dom',
      'react-router-dom',
      'babel-polyfill',
    ],
  },
  output: {
    filename: 'vendors.dll.js',
    path: path.resolve(__dirname, '../../client-dist'),
    // 输出时不要少了这个option
    library: 'vendors_lib',
  },
  plugins: [
    new webpack.DllPlugin({
      context: __dirname,
      // 向外抛出的`vendors.dll.js`代码的具体映射,引用`dll`文件的时候通过它来做映射关系的
      path: path.join(__dirname, '../dist/vendors-manifest.json'),
      name: 'vendors_lib',
    })
  ]
}

// base.js
{
  plugins: [
    new webpack.DllReferencePlugin({
      context: __dirname,
      manifest: require('../dist/vendors-manifest.json'),
    }),
  ]
}

这样在watch文本时,打包就会跳过verdors中设有的这个包了。
有好几要小心的,如若最后必要上传那个静态能源,记得连带着verdors.dll.js壹并上传

在本地开发时,vendors文件并不会活动注入到html模版中去,所以大家有应用了另3个插件,add-asset-html-webpack-plugin。
与此同时在运用中或者还会遇见webpack可是次数的双重包装,那些须求布署ignore来解决-.-:

// dev.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin')

{
  plugins: [
    // 将`ejs`模版文件放到目标文件夹,并注入入口`js`文件
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../index.ejs'),
      filename: path.resolve(__dirname, '../../views/index.ejs'),
    }),
    // 将`vendors`文件注入到`ejs`模版中
    new AddAssetHtmlPlugin({
      filepath: path.resolve(__dirname, '../../client-dist/vendors.dll.js'),
      includeSourcemap: false,
    }),
    // 忽略`ejs`和`js`的文件变化,避免`webpack`无限重新打包的问题
    new webpack.WatchIgnorePlugin([
      /\.ejs$/,
      /\.js$/,
    ]),
  ]
}

1.安装node.js

此间就不详细说了,请看本身的上1篇作品《ES6条件搭建》里面有详尽表达。

编写制定基本模版

接下去,让大家编辑3在那之中坚模版文件,来营造整个网址的基调。

咱俩先在templates文件夹下创立一个html文件base.html,并依照本身的喜好编写三个带有导航栏和菜单的html文件。

大家在个html文件必要改变的地方投入四个入口,如下图:

base.html

在意,那段代码中有四个可以轮换的输入:

{% block title %}{% endblock %}

{% block content %}{% endblock %}

通晓了是哪些地点还在使用JavaScript,那件事情就变得很好消除了,从营造筑工程具(Webpack)起始,每个击破,将那个全体交换为TypeScript

TypeScript相关的布局

TS的配置分了两块,二个是webpack的布置,另三个是tsconfig的配置。

首先是webpack,针对tstsx文本大家应用了七个loader

{
  rules: [
    {
      test: /\.tsx?$/,
      use: ['babel-loader', 'ts-loader'],
      exclude: /node_modules/,
    }
  ],
  resolve: {
    // 一定不要忘记配置ts tsx后缀
    extensions: ['.tsx', '.ts', '.js'],
  }
}

ts-loader用于将TS的部分特色转换为JS同盟的语法,然后实施babel开展拍卖react/jsx连带的代码,最后生成可举办的JS代码。

然后是tsconfig的配置,ts-loader的实践是依托于此间的安插的,大约的安排如下:

{
  "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"
  ]
}

2.安装TypeScript编写翻译工具

TypeScript源码须要开始展览编译现在才能运作,Node.js提供了编写翻译环境。
设置好Node.js后,打开cmd窗口,输入以下命令
npm install -g typescript
安装成功后就足以因此 tsc 命令编写翻译TypeScript源码。能够通过 tsc -v
命令查看当前TypeScript版本。

4858美高梅 2

typescript版本.png

创制页面文件目录

在根目录下创办文件夹pages用于存款和储蓄最后的页面文件:

pages目录地点

然后,和方面壹样,我们须求在settings.py中装置这么些目录的门道:

页面路径

然后,大家在views.py中开创3个视图函数,用于转移页面。

页面的视图函数

后来,大家在templates文件夹中开创3个page.html页面模版,这几个模版继承自base.html,同时会透过刚成立的page视图函数字传送入一个模板成分,那样大家就能够通过向视图函数page中传入区别的参数,让page.html展现包罗不相同pages文件夹下成分的页面文件了。

Webpack 的 TypeScript 达成版本

在这8102年,很幸福,Webpack官方已经协助了TypeScript编纂配置文件,文书档案地址。
除了TypeScript以外还支持JSXCoffeeScript的解释器,在那就忽略它们的留存了

ESLint的配置

近日那段时间,大家团队依照airbnbESLint规则实行了有的自定义,创设了自家的eslint-config-blued
再就是还存在了react和typescript的四个衍生版本。

关于ESLint的布局文件.eslintrc,在本项目中留存两份。3个是根目录的blued-typescript,另三个是client-src下的blued-react

  • blued-typescript
    因为根目录的越多用于node品种,所以没要求把react怎么样的注重性也装进来。

    # .eslintrc
    extends: blued-typescript

    # client-src/.eslintrc
    extends:

    - blued-react
    - blued-typescript
    

二个亟需小心的小细节
因为大家的reacttypescript达成版本中都用到了parser
react采取的是babel-eslint,typescript行使的是typescript-eslint-parser。
但是parser唯其如此有2个,从option的命名中就足以看出extendspluginsrules,到了parser就从未复数了。
所以那两个插件在extends中的顺序就变得很关键,babel现行反革命并无法驾驭TS的语法,但好像babel开发者有帮衬TS的意愿。
但就当下的话,一定要力保react在前,typescript在后,这样parser才会动用typescript-eslint-parser来拓展覆盖。

使用Visual Studio Code开发

创设页面文件模版

在templates文件夹下创造1个文本page.html,文件代码如下:

page.html

率先行代码表示那些html继承了base.html

日后的五个代码块则用来替换base.html中留空的多个代码块。

第4行{% include page %}是视图函数将模版成分传入的输入。

借助于的设置

率先是要设置TypeScript连锁的壹套各个正视,包含解释器及该语言的主导模块:

npm install -D typescript ts-node

typescript为那么些语言的中坚模块,ts-node用以直接实施.ts文本,而不必要像tsc那么会编译输出.js文件。

ts-node helloworld.ts

因为要在TypeScript环境下使用Webpack连锁的东东,所以要安装相应的types
也就是Webpack所对应的那个*.d.ts,用来报告TypeScript那是个什么样指标,提供怎么样艺术。

npm i -D @types/webpack

局地常用的pLugin都会有照应的@types文本,能够简单的经过npm info @types/XXX来检查是或不是留存

假使是某些小众的plugin,则恐怕要求协调创设对应的d.ts文本,例如大家直接在用的qiniu-webpack-plugin,这几个就从不对号入座的@types包的,所以就和好创办一个空文件来报告TypeScript那是个啥:

declare module 'qiniu-webpack-plugin' // 就一个简单的定义即可

// 如果还有其他的包,直接放到同一个文件就行了
// 文件名也没有要求,保证是 d.ts 结尾即可

放置的任务并未有怎么范围,随便丢,一般提出放手types文件夹下

最终正是.ts文本在执行时的一部分配备文件设置。
用来执行Webpack.ts文件对tsconfig.json有一对纤维须要。
compilerOptions下的target分选必须是es5,那么些代表着输出的格式。
以及module渴求选拔commonjs

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "esModuleInterop": true
  }
}

但一般来讲,执行Webpack的同级目录都早已存在了tsconfig.json,用于实际的前端代码编译,很恐怕七个布局文件的参数并不平等。
比方因为要选用Webpack去修改真正的代码配置参数肯定是不可取的。
故此大家就会用到那般七个包,用来改变ts-node执行时所注重的布局文件:tsconfig-paths

Readme中发现了那样的传教:If process.env.TS_NODE_PROJECT is set it will be used to resolved tsconfig.json
Webpack的文书档案中一样也论及了那句,所以那是叁个相配的点子,在指令运营时钦赐二个门道,在不影响原本配置的景观下创办一个供Webpack装进时选拔的布局。

  1. 将上述的配置文件改名字为其余名称,Webpack文书档案示例中为tsconfig-for-webpack-config.json,那里就径直沿用了
  2. 下一场添加npm script如下

{
  "scripts": {
    "build": "TS_NODE_PROJECT=tsconfig-for-webpack-config.json webpack --config configs.ts"
  }
}

node层的修改

而外下面提到的双边公用代码以外,还索要加上多个controller用于吐页面,因为使用的是routing-controllers以此库,渲染三个静态页面棉被服装进的不胜棒,仅仅供给修改三个页面,三个用以安装render模版的根目录,另贰个用来设置要吐出来的模板名称:

// controller/index.ts
import {
  Get,
  Controller,
  Render,
} from 'routing-controllers'

@Controller('/')
export default class {
  @Get('/')
  @Render('index') // 指定一个模版的名字
  async router() {
    // 渲染页面时的一些变量
    // 类似之前的 ctx.state = XXX
    return {
      title: 'First TypeScript React App',
    }
  }
}

// app.ts
import koaViews from 'koa-views'

// 添加模版所在的目录
// 以及使用的渲染引擎、文件后缀
app.use(koaViews(path.join(__dirname, '../views'), {
  options: {
    ext: 'ejs',
  },
  extension: 'ejs',
}))

假若是四个页面,那就创办三个用来Renderts文件就好了

以下目录是个简单的demo

4858美高梅 3

demo.png

要害不外乎但不防止以下多少个目录和文书

/ts:TypeScript源码文件存放的文件夹

/js:编写翻译之后生成的JavaScript文件存放的文本夹

安装U牧马人L与视图函数的路由

最后一步,我们需求配备urls.py用于关联url与视图函数。

urls.py

文本的编写制定

至于配置文件,从JavaScript切换到TypeScript实质上并不会有太大的改观,因为Webpack的配备文件大多都以写死的文件/常量。
成都百货上千类型都是自动生成的,基本能够不要手动钦命,3个简便的示范:

import { Configuration } from 'webpack'

const config: Configuration = {
  mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
}

export default config

Configuration是一个Webpack概念的接口(interface),用来规范二个目的的作为。
VS Code下按住Command +
单击能够向来跳转到具体的webpack.d.ts概念文件那里,能够看出详细的定义音信。
4858美高梅 4
各样常用的条条框框都写在了此地,使用TypeScript的3个利益正是,当要贯彻八个功能时您不再须要去网址上查询相应要安顿哪些,能够直接翻看d.ts的定义。
万1注释写得丰富完善,基本能够算作文书档案来用了,而且在VS Code编辑器中还有动态的提示,以及一些不当的拨乱反正,比如上述的NODE_ENV的拿走,假设直白写process.env.NODE_ENV || 'development'是会抛出贰个拾叁分的,因为从d.ts中可以看出,关于mode唯有多个有效值productiondevelopemntnone,而process.env.NODE_ENV鲜明只是1个字符串类型的变量。
4858美高梅 5
由此大家须求使用长富运算符保障传入的参数一定是大家想要的。

以及在编排的历程中,即使有一对自定义的plugin等等的,恐怕在接纳的经过中会抛卓殊提示说有些对象不是实用的Plugin指标,一个很简短的诀要,在相应的plugin末端添加二个as webpack.Plugin即可。

在这里TypeScript所做的只是静态的检查,并不会对实在的代码执行造成别的影响,即使类型因为强行as而改变,也只是编写翻译期的改动,在实际执行的JavaScript代码中依然弱类型的

在形成了上述的操作后,再实行npm run XXX就足以平昔运行TypeScript版本的Webpack配置咯。

深坑,注意

目前的routing-controller对于Koa的支撑还不是很好,(原著者对Koa并不是很理解,导致Render对应的接口被呼吁三遍现在,后续全部的别的的接口都会一向回到该模版文件,原因是在承受模版渲染的URL接触时,本应再次来到数据,可是最近的拍卖却是添加了一在那之中间件到Koa中,所以任何请求都会将该模版文件作为数据来回到)所以@Render并无法适用于Koa驱动。
而是小编曾经付出了PR了,跑通了测试用例,坐等被联合代码,然则那是3个一时的改动方案,涉及到这几个库针对外部中间件注册的种种难题,所以对于app.ts还要有卓殊的修改才能够达成。

// app.ts 的修改
import 'reflect-metadata'
import Koa from 'koa'
import koaViews from 'koa-views'
import { useKoaServer } from 'routing-controllers'
import { distPath } from './config'

// 手动创建koa实例,然后添加`render`的中间件,确保`ctx.render`方法会在请求的头部就被添加进去
const koa = new Koa()

koa.use(koaViews(path.join(__dirname, '../views'), {
  options: {
    ext: 'ejs',
  },
  extension: 'ejs',
}))

// 使用`useKoaServer`而不是`createKoaServer`
const app = useKoaServer(koa, {
  controllers: [`${__dirname}/controllers/**/*{.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',
    })
  }
}

眼前的演示代码应用的顶端的方案

tsconfig.json:TypeScript编写翻译配置文件

别的.vscode是VS
Code开发工具特有的文本夹,重要用来存放在调节和测试时必要动用的安顿文件。

pages页面代码块

接下去,大家就足以由此在pages文件夹下添加差异的html代码块文件,那么些文件名会被当作视图函数的参数,并将相应的html块替换掉base.html中的
{% block content %}{%   endblock %} 的始末。

大家先在pages目录下创设多少个index.html作为默许的主页页面举办展示。

比如我们在index.html中加入以下代码块。

index.html

那么网址则会在暗许状态下显得:

探索时期的壹件好玩的事

因为小编的品类根目录已经设置了ts-node,而前者项目是作为内部的2个文本夹存在的,所以就从不重新举办设置。
那就推动了贰个令人骨痿的标题。

率先全体流程走完之后,作者直接在命令行中输入TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts
到家运维,然后将那行命令放到了npm scripts中:

{
  "scripts": {
    "start": "TS_NODE_PROJECT=XXX.json NODE_ENV=dev webpack --config ./webpack/dev.ts"
  }
}

重复运转npm start,发现如故出错了-.-,提醒笔者说import语法不可能被辨认,那么些很扎眼正是未有利用大家在ts_NODE_PROJECT中内定的config文件。
刚初阶并不知道难点出在哪,因为这几个在命令行中央直机关接执行并从未其它难题。
中间已经疑惑是或不是是环境变量未有被正确安装,还运用了cross-env本条插件,甚至将下令写到了3个sh文件中展开实施。
不过难点如故留存,后来在3个群中跟同伴们谈起了那几个题目,有人提议,你是或不是全局安装了ts-node
反省过后发现,果然没有错,在命令行执行时选用的是全局的ts-node,但是在npm scripts中应用的是本地的ts-node
在命令行环境执行时还认为是会活动搜索父文件夹node_modules上面包车型地铁依赖,其实是运用的全局包。
婴孩的在client-src文件夹下也设置了ts-node就解决了那个难题。
全局重视害人。。

小结

从那之后,2个完好的TS前后端项目架构就曾经搭建实现了(剩下的义务正是往骨架里边填代码了)。
自笔者早已更新了前面包车型大巴typescript-exmaple
在当中添加了本次重构所利用的局地前端TS+React的言传身教,还包蕴针对@Render的部分相配。

TypeScript是叁个很棒的想法,消除了N多javaScript种让人非议的标题。
选拔静态语言来拓展付出不仅能够增强花费的效用,同时还是能减低错误出现的概率。
结缘着强劲的vs code,Enjoy it.

若是在动用TS的经过中有哪些难题、或然有哪些更加好的想法,欢迎来交流座谈。

tsconfig.json配置 (放在项目标根目录下)
{
  "compilerOptions": {
        "target": "es5",
        "noImplicitAny": false,
        "module": "commonjs",
        "removeComments": true,
        "sourceMap": false,
        "outDir": "js"
    },
    "include":[
        "ts"
    ],
    "exclude": [
        "js"
    ]
}
//target:编译之后生成的JavaScript文件需要遵循的标准。有三个候选项:es3、es5、es2015。
//noImplicitAny:为false时,如果编译器无法根据变量的使用来判断类型时,将用any类型代替。为true时,将进行强类型检查,无法推断类型时,提示错误。
//module:遵循的JavaScript模块规范。主要的候选项有:commonjs、AMD和es2015。为了后面与node.js保持一致,我们这里选用commonjs。
//removeComments:编译生成的JavaScript文件是否移除注释。
//sourceMap:编译时是否生成对应的source map文件。这个文件主要用于前端调试。当前端js文件被压缩引用后,出错时可借助同名的source map文件查找源文件中错误位置。
//outDir:编译输出JavaScript文件存放的文件夹。
//include、exclude:编译时需要包含/剔除的文件夹

测试用例的改建

前边的Webpack改为TypeScript多数缘由是因为网瘾所致。
然则测试用例的TypeScript改建则是一个能相当大提升功能的操作。

配置编写翻译和调剂文件

在.vscode文件夹中添加 tasks.json文件

4858美高梅 6

tasks.json.png

为什么要在测试用例中央银行使 TypeScript

测试用例使用chai来编写,(之前的Postman也是用的chai的语法)
chai提供了一多元的语义化链式调用来实现断言。
在在此之前的分享中也涉及过,这么多的一声令下你并不供给完全记住,只知道多少个expect(XXX).to.equal(true)就够了。

然则那样的全文to.equal(true)是巨丑无比的,而壹旦应用那一个语义化的链式调用,在不懂行的气象下很不难就会拿走:

Error: XXX.XXX is not a function

因为那确实有三个法门难点,必供给写过多才能记住调用规则,各样notincludes的操作。
而是接入了TypeScript随后,那一个难题都解决了。
也是前方提到的,全体的TypeScript模块都有其相应的.d.ts文本,用来报告大家以此模块是做哪些的,提供了如何能够接纳。
也正是说在测试用例编写时,大家得以经过动态提示来十分的快的书写断言,而不要求结合着文书档案去进行“翻译”。

4858美高梅 7
4858美高梅 8

tasks.json配置
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "0.1.0",
    "command": "tsc",
    "isShellCommand": true,
    "args": ["-p", "./typescript"],
    "showOutput": "always",
    "problemMatcher": "$tsc"
}

配置完毕后,使用Ctrl+Shift+B 运行编写翻译,倘使VS
Code的OUTPUT窗口没有任何相当消息彰显,则表示编写翻译成功。在js文件夹里将会转变编写翻译后的JavaScript文件

安顿好之后大家启用调节和测试情势,

修改生成的launch.json文本内容,钦定运营文件的路子

4858美高梅 9

路径.png

开辟调节和测试台

启航调节和测试

4858美高梅 10

debugger.png

假设出现这行警告

4858美高梅 11

警告.png

打开launch.json文本改二个安排

4858美高梅 12

改这里.png

运用方式

假使是前边有写过mochachai的童鞋,基本上修改文件后缀+安装相应的@types即可。
能够直接跳到此处来:始于编写制定测试脚本
不过1旦对测试用例感兴趣,可是并从未使用过的童鞋,能够看上面包车型地铁多个大旨步骤。

OK

前天能够写大家的 ts 代码了

4858美高梅 13

ts代码.png

安装重视

  1. TypeScript相关的装置,npm i -D typescript ts-node
  2. Mochachai有关的安装,npm i -D mocha chai @types/mocha @types/chai
  3. 假若须求涉及到部分API的请求,能够附加安装chai-httpnpm i -D chai-http @types/chai-http

条件的重视性就已经完结了,假使额外的应用壹些别样的插件,记得安装相应的@types文本即可。
万壹有采取ESLint之类的插件,恐怕会唤醒modules无法不存在于dependencies而非devDependencies
这是ESLint的import/no-extraneous-dependencies规则导致的,针对这么些,大家当前的方案是加上1些不及:

import/no-extraneous-dependencies:
  - 2
  - devDependencies:
    - "**/*.test.js"
    - "**/*.spec.js"
    - "**/webpack*"
    - "**/webpack/*"

针对这么些目录下的文本/文件夹不开始展览校验。不错,webpack的应用也会遭逢这些难点

按下 ctrl+shift+B编译

大家的 js 代码编写翻译出来了 在灵梦那边

4858美高梅 14

js代码.png

始于编写制定测试脚本

假设是对原有的测试脚本实行改动,无外乎修改后缀、添加1些必备的种类注脚,不会对逻辑造成别的改动。

运营调节和测试

调节台出口了不利结果

4858美高梅 15

打字与印刷结果.png

一个简单易行的以身作则

// number-comma.ts
export default (num: number | string) => String(num).replace(/\B(?=(\d{3})+$)/g, ',')

// number-comma.spec.ts
import chai from 'chai'
import numberComma from './number-comma'

const { expect } = chai

// 测试项
describe('number-comma', () => {
  // 子项目1
  it('`1234567` should transform to `1,234,567`', done => {
    expect(numberComma(1234567)).to.equal('1,234,567')
    done()
  })

  // 子项目2
  it('`123` should never transform', done => {
    const num = 123
    expect(numberComma(num)).to.equal(String(num))
    done()
  })
})

假若全局未有设置mocha,记得将指令写到npm script中,大概经过下述格局实施

./node_modules/mocha/bin/mocha -r ts-node/register test/number-comma.spec.ts

# 如果直接这样写,会抛出异常提示 mocha 不是命令
mocha -r ts-node/register test/number-comma.spec.ts

mocha有星星点点相比好的是提供了-r一声令下来让您手动钦命执行测试用例脚本所选用的解释器,那里直接设置为ts-node的路径ts-node/register,然后就足以在背后直接跟两个文件名(恐怕是一对通配符)。

眼下我们在品种中批量履行测试用例的下令如下:

{
  "scripts": {
    "test": "mocha -r ts-node/register test/**/*.spec.ts"
  }
}

npm test能够一直调用,而不需求丰裕run命令符,类似的还有startbuild等等

一键进行未来就能够赢得我们想要的结果了,再也不用担心1些代码的改观会影响到任何模块的逻辑了
(前提是当真写测试用例)

4858美高梅 16

小结

做完上面两步的操作之后,我们的门类就贯彻了百分之百的TypeScript化,在其余地点享受静态编写翻译语法所拉动的补益。
屈居更新后的代码含量截图:

4858美高梅 17

如今本着TypeScript做了成都百货上千业务,从Node.jsReact以及此番的WebpackMocha+Chai
TypeScript因为其设有八个编写翻译的进度,非常的大的降低了代码出bug的恐怕,进步程序的稳定度。
左右逢源切换成TypeScript尤其能够下落在三种语法之间相互切换时所拉动的不须要的消耗,祝我们搬砖欢腾。

后面关于 TypeScript 的笔记

  • TypeScript在node项目中的实践
  • TypeScript在react项目中的实践

3个总体的 TypeScript 示例

typescript-example

欢迎各位来商量关于TypeScript使用上的部分难点,针对稳重的感觉不足之处也欢迎提议。

参考资料

  • ts-node
  • configuration-languages |
    webpack
  • mochajs
  • chaijs

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有