我正在尝试引入 cls-rtracer,但在实例化它时,它是未定义的。
代码是用 TypeScript 编写的,使用面向对象的范式而不是函数式。
在 NPM 中发布的库示例是功能性的。
我已将它即将到来的地方评论为未定义。
在这个 express 应用中引入任何其他中间件似乎很简单,除了 cls-rtracer
这是代码:
import express, {NextFunction, Response, Request} from 'express';
import * as bodyParser from 'body-parser';
import helmet from 'helmet';
import morgan from 'morgan';
import cors from 'cors';
import swaggerJSDoc from 'swagger-jsdoc';
import swaggerui from 'swagger-ui-express';
import {Controller} from './api/v1/controllers/Controller';
import {logger} from './api/v1/utils/Logger';
import {errorHandler} from './api/v1/utils/ErrorHandler';
import {BaseError} from './api/v1/utils/BaseError';
import {HttpStatusCode} from './api/v1/constants/HttpStatusCode';
import rTracer from 'cls-rtracer';
export const stream = {
write: (text: string) => {
logger.info(text.replace(/\n$/, ''));
},
};
const swaggerOptions = {
swaggerDefinition: {
info: {
title: 'Backend',
descriptions: 'Service',
contact: {
name: '',
},
servers: ['http://localhost:8080//api/v1/domain'],
version: '1.0.1',
},
},
apis: ['./api/v1/routes/*.ts'],
};
const swaggerDocs = swaggerJSDoc(swaggerOptions);
export class App {
public app: express.Application;
public port: number;
constructor(controllers: Controller[], port: number) {
this.app = express();
this.port = port;
this.initializeMiddlewares();
this.initializeHealth();
this.initializeControllers(controllers);
this.initializeErrorHandler();
this.initializeSwagger();
}
private initializeMiddlewares() {
this.app.use(rTracer.expressMiddleware());
const requestId = rTracer.id();
console.log(requestId); // giving undefined
this.app.use(bodyParser.json());
this.app.use(cors());
this.app.use(
morgan(
[
'ip: :remote-addr',
':method', ':url', 'HTTP/:http-version', 'status: :status',
':res[content-length]', 'referrer: :referrer',
'userAgent: :user-agent', 'responseTime: :response-time ms',
].join(' | '),
{stream: stream},
),
);
this.app.use(express.json());
this.app.use(helmet());
}
private initializeControllers(controllers: Controller[]) {
controllers.forEach((controller) => {
this.app.use('/', controller.router);
});
}
private initializeErrorHandler() {
this.app.use(async (req: Request, res: Response, next: NextFunction) => {
const error = new BaseError('Not Found', HttpStatusCode.NOT_FOUND, true, 'Not Found');
next(error);
});
this.app.use(async (error: Error, req: Request, res: Response, next: NextFunction) => {
if (!errorHandler.isTrustedError(error)) {
// @ts-ignore: Unreachable code error
res.status(error.status).json(error);
}
await errorHandler.handleError(error);
// @ts-ignore: Unreachable code error
res.status(error.httpCode || HttpStatusCode.INTERNAL_SERVER).json({error: error});
});
}
private initializeSwagger() {
this.app.use(
'/api-docs',
swaggerui.serve,
swaggerui.setup(swaggerDocs, {explorer: true}),
);
}
private initializeHealth() { }
public listen() {
this.app.listen(this.port, () => {
logger.info(`listening on the port ${this.port}`);
});
}
}
export default App;
为什么它在下面的代码中完美运行:
import express from 'express';
import {CONFIG} from './config';
import MasterRouter from './routers/MasterRouter';
import ErrorHandler from './utils/ErrorHandler';
import rTracer from 'cls-rtracer';
import morgan from 'morgan';
class Server {
public app = express();
public router = MasterRouter;
constructor(
) {
this.correlationalIdMiddleware();
this.loggingMiddleware();
this.routingMiddleware();
this.errorHandlingMiddleWare();
}
correlationalIdMiddleware() {
this.app.use(rTracer.expressMiddleware());
}
loggingMiddleware() {
this.app.use(morgan((tokens, req, res) => {
const requestId = rTracer.id();
return [
`> requestId: ${requestId} -`,
tokens.method(req, res),
tokens.url(req, res),
tokens.status(req, res),
tokens.res(req, res, 'content-length'), '-',
tokens['response-time'](req, res), 'ms',
].join(' ');
}));
}
routingMiddleware() {
this.app.use('/api', this.router);
}
errorHandlingMiddleWare() {
this.app.use((req, res, next) => {
const error = new ErrorHandler(404, 'Not Found');
next(error);
});
this.app.use((error: ErrorHandler, req: any, res: any, next: any) => {
const errorObject = {
status: 'error',
statusCode: error.statusCode,
message: error.message,
};
const requestId = rTracer.id();
console.log(`> requestId: ${requestId} - ${JSON.stringify(errorObject)}`);
res.status(error.statusCode || 500).json(errorObject);
});
}
}
const server = new Server;
server.app.listen(CONFIG.PORT, () => {
console.log(`> Server listening on ${CONFIG.PORT}`);
});