内容简介:原文地址:强类型的接下来开始对基于
原文地址: 使用typescript改造koa开发框架
强类型的 TypeScript 开发体验和维护项目上相比 JavaScript 有着明显的优势,那么对常用的脚手架进行改造也就势在必行了。
接下来开始对基于 koa 框架的 node 后端脚手架进行改造:
- 项目开发环境 和 typescript 编译环境的搭建;
- 对 node 、 koa 、koa中间件和使用到的库 添加类型化支持;
- 基于 typesript 的特性改造项目。
项目开发环境搭建
基于 gulp 搭建开发编译环境, gulp-typescript 插件用于编译 typescript 文件, gulp-nodemon 则可以监控文件内容的变更,自动编译和重启 node 服务,提升开发效率。
npm install -D gulp gulp-nodemon gulp-typescript ts-node typescript
gulp 的配置
gulpfile.js 的设置
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); } // 输出 js 到 dist目录 function toJs() { return src('src/**/*.ts') .pipe(tsProject()) .pipe(dest('dist')); } // nodemon 监控 ts 文件 function runNodemon() { nodemon({ inspect: true, script: 'src/app.ts', watch: ['src'], ext: 'ts', env: { NODE_ENV: 'development' }, // tasks: ['build'], }).on('crash', () => { console.error('Application has crashed!\n'); }); } const build = series(clean, toJs); task('build', build); exports.build = build; exports.default = runNodemon;
typescript 的配置
tsconfig.json 的设置
{ "compilerOptions": { "baseUrl": ".", // import的相对起始路径 "outDir": "./dist", // 构建输出目录 "module": "commonjs", "target": "esnext",// node 环境支持 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 的配置
当然 eslint 也要添加对 typescript 对支持
npm install -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
.eslintrc.json 的设置
{ "env": { "es6": true, "node": true }, "extends": [ "eslint:recommended", "plugin:@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 运行配置
最后就是设置 package.json 的 scripts
"scripts": { "start": "gulp",// dev "build": "gulp build", // output "eslint": "eslint --fix --ext .js,.ts src/", "server": "export NODE_ENV=production && node dist/app" // production server },
添加类型化支持
项目主要使用到了以下的组件
- jsonwebtoken
- koa
- koa-body
- koa-compress
- koa-favicon
- koa-logger
- koa-router
- koa-static
- koa2-cors
- log4js
那么就要安装对应的 type 文件,当然别忘了 @types/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 装饰器 改造项目
.net mvc框架有个很便利的地方就是 使用装饰器对控制器进行配置,现在通过 typescript 的装饰器也可以实现相同的功能。这里需要使用到反射相关的库 reflect-metadata ,用过 Java 或 C# 的小伙伴,对反射的原理一定不陌生。
定义http请求的装饰器
我们再也不需要在路由配置和控制器方法之前来回查找和匹配了
import 'reflect-metadata' import { ROUTER_MAP } from '../constant' /** * @desc 生成 http method 装饰器 * @param {string} method - http method,如 get、post、head * @return Decorator - 装饰器 */ function createMethodDecorator(method: string) { // 装饰器接收路由 path 作为参数 return function httpMethodDecorator(path: string) { return (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'); }; }; } // 导出 http 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 } } }
收集元数据和添加路由
我们已经把装饰器添加到对应控制器的方法上了,那么怎么把元数据收集起来呢?这就需要用到 node 提供的 fs 文件模块, node 服务第一次启动的时候,扫描一遍controller文件夹,收集到所有控制器模块,结合装饰器收集到的metadata,就可以把对应的方法添加到 koa-router 。
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: any[] = []; // 扫描controller文件夹,收集所有controller fs.readdirSync(ctrPath).forEach(name => { if (/^[^.]+?\.(t|j)s$/.test(name)) { modules.push(require(path.join(ctrPath, name)).default) } }); // 结合meta数据添加路由 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 项目脚手架的改造基本完成,源码请查看 koa-server
以上所述就是小编给大家介绍的《使用typescript改造koa开发框架》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Smashing Book
Jacob Gube、Dmitry Fadeev、Chris Spooner、Darius A Monsef IV、Alessandro Cattaneo、Steven Snell、David Leggett、Andrew Maier、Kayla Knight、Yves Peters、René Schmidt、Smashing Magazine editorial team、Vitaly Friedman、Sven Lennartz / 2009 / $ 29.90 / € 23.90
The Smashing Book is a printed book about best practices in modern Web design. The book shares technical tips and best practices on coding, usability and optimization and explores how to create succes......一起来看看 《The Smashing Book》 这本书的介绍吧!