博客
关于我
使用typescript改造koa开发框架
阅读量:420 次
发布时间:2019-03-06

本文共 4671 字,大约阅读时间需要 15 分钟。

Koa 项目脚手架改造

项目开发环境搭建

基于 gulp 搭建开发编译环境,使用 gulp-typescript 编译 TypeScript 文件,gulp-nodemon 监控文件变更,自动编译并重启 Node 服务,提升开发效率。

gulp 配置

const { src, dest, watch, series, task } = require('gulp');const del = require('del');const ts = require('gulp-typescript');const nodemon = require('gulp-nodemon');const tsProject = ts.createProject('tsconfig.json');function clean(cb) {  return del(['dist'], cb);}function toJs() {  return src('src/**/*.ts')    .pipe(tsProject())    .pipe(dest('dist'));}function runNodemon() {  nodemon({    inspect: true,    script: 'src/app.ts',    watch: ['src'],    ext: 'ts',    env: { NODE_ENV: 'development' },  }).on('crash', () => {    console.error('Application has crashed!');  });}const build = series(clean, toJs);task('build', build);exports.build = build;exports.default = runNodemon;

TypeScript 配置

{  "compilerOptions": {    "baseUrl": ".",    "outDir": "./dist",    "module": "commonjs",    "target": "esnext",    "allowSyntheticDefaultImports": true,    "importHelpers": true,    "strict": false,    "moduleResolution": "node",    "esModuleInterop": true,    "forceConsistentCasingInFileNames": true,    "noImplicitAny": true,    "suppressImplicitAnyIndexErrors": true,    "noUnusedParameters": true,    "noUnusedLocals": true,    "noImplicitReturns": true,    "experimentalDecorators": true,    "emitDecoratorMetadata": true,    "allowJs": true,    "sourceMap": true,    "paths": {      "@/*": ["src/*"]    }  },  "include": ["src/**/*"],  "exclude": ["node_modules", "dist"]}

ESLint 配置

{  "env": {    "es6": true,    "node": true  },  "extends": [    "eslint:recommended",    "@typescript-eslint/eslint-recommended"  ],  "globals": {    "Atomics": "readonly",    "SharedArrayBuffer": "readonly"  },  "parser": "@typescript-eslint/parser",  "parserOptions": {    "ecmaVersion": 2018,    "sourceType": "module"  },  "plugins": ["@typescript-eslint"],  "rules": {    "indent": ["warn", 2],    "no-unused-vars": 0  }}

package.json 运行配置

{  "scripts": {    "start": "gulp", // 开发模式    "build": "gulp build", // 生产模式    "eslint": "eslint --fix --ext .js,.ts src/", // 格式化代码    "server": "NODE_ENV=production && node dist/app" // 生成生产服务器  }}

添加类型化支持

项目主要使用以下组件:

  • jsonwebtoken
  • Koa
  • koa-body
  • koa-compress
  • koa-favicon
  • koa-logger
  • koa-router
  • koa-static
  • koa2-cors
  • log4js
  • Node

安装对应的类型定义文件:

npm install -D @types/jsonwebtoken @types/koa @types/koa-compress @types/koa-favicon @types/koa-logger @types/koa-router @types/koa-static @types/koa2-cors @types/log4js @types/node

使用 TypeScript 装饰器改造项目

定义 HTTP 请求的装饰器

import 'reflect-metadata';import { ROUTER_MAP } from '../constant';function createMethodDecorator(method: string) {  return function httpMethodDecorator(path: string) {    return function (proto: any, name: string) {      const target = proto.constructor;      const routeMap = Reflect.getMetadata(ROUTER_MAP, target, 'method') || [];      routeMap.push({ name, method, path });      Reflect.defineMetadata(ROUTER_MAP, routeMap, target, 'method');    };  };}export const post = createMethodDecorator('post');export const get = createMethodDecorator('get');export const del = createMethodDecorator('del');export const put = createMethodDecorator('put');export const patch = createMethodDecorator('patch');export const options = createMethodDecorator('options');export const head = createMethodDecorator('head');export const all = createMethodDecorator('all');

装饰控制器的方法

export default class Sign {  @post('/login')  async login(ctx: Context) {    const { email, password } = ctx.request.body;    const users = await userDao.getUser({ email });    // ...    return ctx.body = { code: 0, message: '登录成功', data };  }  @post('/register')  async register(ctx: Context) {    const { email, password } = ctx.request.body;    const salt = makeSalt();    // ...    return ctx.body = { code: 0, message: '注册成功!', data };  }}

收集元数据和添加路由

import 'reflect-metadata';import fs from 'fs';import path from 'path';import { ROUTER_MAP } from './constant';import { RouteMeta } from './type';import Router from 'koa-router';const addRouter = (router: Router) => {  const ctrPath = path.join(__dirname, 'controller');  const modules: ObjectConstructor[] = [];  fs.readdirSync(ctrPath).forEach(name => {    if (/^[^.]+?\.(t|j)s$/.test(name)) {      modules.push(require(path.join(ctrPath, name)).default);    }  });  modules.forEach(m => {    const routerMap: RouteMeta[] = Reflect.getMetadata(ROUTER_MAP, m, 'method') || [];    if (routerMap.length) {      const ctr = new m();      routerMap.forEach(route => {        const { name, method, path } = route;        router[method](path, ctr[name]);      });    }  });};export default addRouter;

最后

通过上述优化,Koa 项目的脚手架改造工作基本完成。

转载地址:http://icduz.baihongyu.com/

你可能感兴趣的文章
NullPointerException Cannot invoke setSkipOutputConversion(boolean) because functionToInvoke is null
查看>>
null可以转换成任意非基本类型(int/short/long/float/boolean/byte/double/char以外)
查看>>
Number Sequence(kmp算法)
查看>>
Numix Core 开源项目教程
查看>>
numpy
查看>>
Numpy 入门
查看>>
NumPy 库详细介绍-ChatGPT4o作答
查看>>
NumPy 或 Pandas:将数组类型保持为整数,同时具有 NaN 值
查看>>
numpy 或 scipy 有哪些可能的计算可以返回 NaN?
查看>>
numpy 数组 dtype 在 Windows 10 64 位机器中默认为 int32
查看>>
numpy 数组与矩阵的乘法理解
查看>>
NumPy 数组拼接方法-ChatGPT4o作答
查看>>
numpy 用法
查看>>
Numpy 科学计算库详解
查看>>
Numpy.fft.fft和numpy.fft.fftfreq有什么不同
查看>>
numpy.linalg.norm(求范数)
查看>>
Numpy.ndarray对象不可调用
查看>>
Numpy.VisibleDeproationWarning:从不整齐的嵌套序列创建ndarray
查看>>
Numpy:按多个条件过滤行?
查看>>
Numpy:条件总和
查看>>