Compared with JavaScript, strong-type TypeScript development experience and maintenance projects, it is imperative to transform commonly used scaffolding.
Next, we will start to renovate the node back-end scaffolding based on the koa framework:
- Construction of project development environment and typescript compilation environment;
- Add typed support for node, koa, koa middleware and used libraries;
- Feature modification project based on typescript.
Project development environment construction
Build a development and compilation environment based on gulp. The gulp-typescript plug-in is used to compile typescript files. gulp-nodemon can monitor changes in file content, automatically compile and restart node services, and improve development efficiency.
npm install -D gulp gulp-nodemon gulp-typescript ts-node typescript
gulp configuration
Settings
const { src, dest, watch, series, task } = require('gulp'); const del = require('del'); const ts = require('gulp-typescript'); const nodemon = require('gulp-nodemon'); const tsProject = (''); function clean(cb) { return del(['dist'], cb); } // Output js to dist directoryfunction toJs() { return src('src/**/*.ts') .pipe(tsProject()) .pipe(dest('dist')); } // nodemon monitors ts filesfunction runNodemon() { nodemon({ inspect: true, script: 'src/', watch: ['src'], ext: 'ts', env: { NODE_ENV: 'development' }, // tasks: ['build'], }).on('crash', () => { ('Application has crashed!\n'); }); } const build = series(clean, toJs); task('build', build); = build; = runNodemon;
typescript configuration
Settings
{ "compilerOptions": { "baseUrl": ".", // The relative start path of import "outDir": "./dist", // Build the output directory "module": "commonjs", "target": "esnext",// Node environment supports 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, // Turn on the decorator "emitDecoratorMetadata": true, "allowJs": true, "sourceMap": true, "paths": { "@/*": [ "src/*" ] } }, "include": [ "src/**/*" ], "exclude": [ "node_modules", "dist" ] }
eslint configuration
Of course, eslint also needs to add support for typescript
npm install -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
.
{ "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 } }
Run the configuration
Finally, set 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 },
Add typed support
The project mainly uses the following components
jsonwebtoken
koa
koa-body
koa-compress
koa-favicon
koa-logger
koa-router
koa-static
koa2-cors
log4js
Then you need to install the corresponding type file, of course, don't forget @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
Rebuild a project using typescript decorator
A very convenient part of the .net mvc framework is to use decorators to configure the controller. Now the same function can be achieved through the typescript decorator. Here we need to use reflect-metadata, a library related to reflection. Friends who have used Java or C# must be familiar with the principle of reflection.
Decorators that define http requests
We no longer need to look up and match back and forth before routing configuration and controller methods
import 'reflect-metadata' import { ROUTER_MAP } from '../constant' /** * @desc Generate http method decorator * @param {string} method - http method, such as get, post, head * @return Decorator - Decorator */ function createMethodDecorator(method: string) { // The decorator receives the route path as a parameter return function httpMethodDecorator(path: string) { return (proto: any, name: string) => { const target = ; const routeMap = (ROUTER_MAP, target, 'method') || []; ({ name, method, path }); (ROUTER_MAP, routeMap, target, 'method'); }; }; } // Export http method decoratorexport 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');
Methods to decorate the controller
export default class Sign { @post('/login') async login (ctx: Context) { const { email, password } = ; const users = await ({ email }); // ... return = { code: 0, message: 'Login successfully', data }; } @post('/register') async register (ctx: Context) { const { email, password } = ; const salt = makeSalt(); // ... return = { code: 0, message: 'Registered successfully! ', data } } }
Collect metadata and add routes
We have added the decorator to the corresponding controller method, so how do we collect metadata? This requires the use of the fs file module provided by node. When the node service is started for the first time, scan the controller folder and collect all controller modules. Combined with the metadata collected by the decorator, you can add the corresponding method to the 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 = (__dirname, 'controller'); const modules: ObjectConstructor[] = []; // Scan the controller folder to collect all controllers (ctrPath).forEach(name => { if (/^[^.]+?\.(t|j)s$/.test(name)) { (require((ctrPath, name)).default) } }); // Add routes in combination with meta data (m => { const routerMap: RouteMeta[] = (ROUTER_MAP, m, 'method') || []; if () { const ctr = new m(); (route => { const { name, method, path } = route; router[method](path, ctr[name]); }) } }) } export default addRouter
at last
In this way, the transformation of the scaffolding of the koa project is basically completed. Please check the source codekoa-server
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.