【发布时间】:2020-07-14 03:44:26
【问题描述】:
我是使用 NodeJS 和 mocha 的 socket.io 的初学者。使用 socket.io 客户端和服务器后,出现以下错误
Router.use() requires a middleware function but got a undefined 在项目构建期间。以下是文件和代码详细信息
后端/main.ts
const app = express()
const http = require('http').createServer(app)
...
app.use('/api', require('./routes/api'))
...
export const io = require('socket.io')(http)
io.listen(http)
io.on('connection', (client: SocketIO.Socket) => {
// eslint-disable-next-line no-console
console.log('Socket open Connection')
client.on('disconnect', () => {
// eslint-disable-next-line no-console
console.log('socket disconnect')
})
})
...
后端/路由/api/index.ts
const router = Router()
// Global middleware for all /api routes
router.use('/ping', ping)
router.use('/crm', isLoggedIn, ensureAccessToken, crmSource)
router.use('/app', isLoggedIn, ensureAccessToken, app)
router.use('/app-users', isLoggedIn, ensureAccessToken, ensureIsGlobalTeamMember, appUsers)
router.use('/business', isLoggedIn, ensureAccessToken, ensureIsAdmin, business)
router.use('/app-offers', isLoggedIn, ensureAccessToken, appOffers)
router.use('/app-contracts', isLoggedIn, ensureAccessToken, appContracts)
router.use('/app-order', isLoggedIn, ensureAccessToken, appOrders)
router.use('/app-export', isLoggedIn, ensureAccessToken, appDetailsExport)
router.use('/app-global-settings', isLoggedIn, ensureAccessToken, appGlobalSettings)
if (config.environment === 'local' || config.environment === 'dev') {
router.use('/translations', translationRoutes)
}
// Non-existent API routes should return 404, not the HTML page
router.use((_req, res) => {
res.status(404).end()
})
// export default router
module.exports = router
后端/路由/api/crmSource/ts
const router = Router()
router.get('/', (req: ApiRequest, res: Response) => { ... } )
router.get('/source/number/:sourceNumber', (req: ApiRequest, res: Response) => { ... } )
...
export default router
后端/路由/api/appUsers.ts
const router = Router()
router.post(...)
router.delete(...)
export default router
全局中间件路由器中的所有其他中间件都以相同的方式编写。
当我从 main.ts 导入 io 以在以下文件中进行套接字通信时 checkout-offer.ts
import {io as socketIoConnection} from './main'
...
function checkoutOffer(db, logger, offer, token) {
socketIoConnection.emit('saveOffer')
await db.saveCheckoutOffer(offer, logger, token)
socketIoConnection.emit('offerCheckedOut')
return db.getCheckedOffer(db, updatedOffer.id)
}
...
我在使用 mocha 的测试版本中遇到以下错误。没有运行 mocha 测试的套接字实现在应用程序中运行得非常好。但是在运行npm run test 时出现此错误。
> myproject@1.0.0 test /Users/<user>/myproject
> npm-run-all --sequential test:unit lint test:api test:browser
> myproject@1.0.0 test:unit /Users/<user>/myproject
> NODE_ICU_DATA=node_modules/full-icu mocha "test/unit/**/*test.{tsx,ts}"
ERROR myproject: Router.use() requires a middleware function but got a undefined
TypeError: Router.use() requires a middleware function but got a undefined
at Function.use (/Users/<user>/myproject/node_modules/express/lib/router/index.js:458:13)
at Object.<anonymous> (/Users/<user>/myproject/backend/routes/api/index.ts:28:8)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module.m._compile (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:439:23)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.<anonymous> (/Users/<user>/myproject/backend/main.ts:91:17)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module.m._compile (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:439:23)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.<anonymous> (/Users/<user>/myproject/backend/finalize-offer.ts:18:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module.m._compile (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:439:23)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.<anonymous> (/Users/<user>/myproject/backend/routes/api/offers.ts:15:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module.m._compile (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:439:23)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.<anonymous> (/Users/<user>/myproject/test/unit/i18n-test.ts:8:1)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module.m._compile (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:439:23)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.require.extensions.(anonymous function) [as .ts] (/Users/<user>/myproject/node_modules/ts-node/src/index.ts:442:12)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at /Users/<user>/myproject/node_modules/mocha/lib/mocha.js:231:27
at Array.forEach (<anonymous>)
at Mocha.loadFiles (/Users/<user>/myproject/node_modules/mocha/lib/mocha.js:228:14)
at Mocha.run (/Users/<user>/myproject/node_modules/mocha/lib/mocha.js:536:10)
at Object.<anonymous> (/Users/<user>/myproject/node_modules/mocha/bin/_mocha:573:18)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)
package.json 测试脚本
"test": "npm-run-all --sequential test:unit lint test:api test:browser",
"lint": "eslint --ext .ts,.tsx,.js . && stylelint \"**/*.less\" \"**/*.css\"",
"lint-fix": "eslint --ext .ts,.tsx,.js . --fix && stylelint \"**/*.less\" \"**/*.css\" --fix",
"test:unit": "NODE_ICU_DATA=node_modules/full-icu mocha \"test/unit/**/*test.{tsx,ts}\"",
"test:api": "NODE_ICU_DATA=node_modules/full-icu mocha test/api/**/*.ts",
"test:browser": "NODE_ICU_DATA=node_modules/full-icu mocha test/browser/**/*.ts",
这是在backend/routes/api/index.ts(上面提供)全局路由器中间件router.use('/app-offers', isLoggedIn, ensureAccessToken, appOffers)中导入的中间件
后端/路由/api/appOffers.ts
/* imports */
const router = Router()
const upload = multer()
router.post('/offer/:offerId', (req: ApiRequest, res: Response) => {
...
})
router.get('/:offerId', (req: ApiRequest, res: Response) => {
...
})
router.post('/offer/:offerId/finalize', (req: ApiRequest, res: Response) => {
...
})
export const setActiveOfferAsInCrm = (restUrl: string, accessToken: string, logger: Logger) => async (offers: SavedOffer[]): Promise<SavedOffer[]> => {
...
}
router.post('/:offerId/activate', (req: ApiRequest, res: Response) => {
...
})
router.post('/:offerId/doc-attachment/upload/:type', upload.single('file'), async (req: ApiRequest, res: Response) => {
...
})
router.post('/:offerId/doc-attachment/:attachmentId/delete', async (req: ApiRequest, res: Response) => {
...
})
router.post('/:offerId/cloning', async (req: ApiRequest, res: Response) => {
...
})
router.post('/:offerId/doc-attachment', async (req: ApiRequest, res: Response) => {
...
})
enum AttachmentTypes {
_Docx = 'docx',
_Jpg = 'jpg',
_Pdf = 'pdf',
_Xlsx = 'xlsx',
_Csv = 'csv'
}
type DocumentType = AttachmentTypes._Docx | AttachmentTypes._Jpg | AttachmentTypes._Pdf | AttachmentTypes._Xlsx
export const documentTypes: DocumentType[] = [AttachmentTypes._Docx, AttachmentTypes._Jpg, AttachmentTypes._Pdf, AttachmentTypes._Xlsx]
export function getDocumentFilename(documentType: DocumentType) {
switch (documentType) {
...
}
}
function getEmailAttachmentName(t: TranslationFunction, AttachmentTypes: AttachmentTypes, extension: string): string {
const prefixAndTranslate = (key: string) => t('contractPdf.' + key)
switch (AttachmentTypes) {
...
}
}
function getEmailAdditionalAttachmentName(t: TranslationFunction, AttachmentTypesNumber: number, originalName: string): string {
const prefixAndTranslate = (key: string) => t('contractPdf.' + key)
return prefixAndTranslate('AttachmentTypes') + ' ' + AttachmentTypesNumber + ' - ' + originalName
}
async function loadAndAttachDocument(logger: Logger,
t: TranslationFunction,
businessId: BusinessId,
language: Language,
documentType: DocumentType): Promise<AttachmentFile | undefined> {
...
}
export function getDocumentPath(businessId: BusinessId, language: Language, documentType: DocumentType): string {
return path.join(__dirname, '..', '..', 'assets', 'AttachmentTypeses', businessId, language, getDocumentFilename(documentType))
}
router.post('/:offerId/email', async (req: ApiRequest, res: Response) => {
...
})
export default router
【问题讨论】:
-
当然@jfriend00。我也会发布那些中间件路由器。我会花一些时间来发布它们。非常感谢您的回复。
-
@jfriend00 我已经发布了一些我在全球中间件路由器中使用过的中间件。所有其他中间件都与 appUsers.ts 时尚相似。
-
到目前为止,您错过了最重要的线索(我在原始评论中问您的第一个问题)。错误发生在代码的哪一行
router.use()上?该信息位于错误转储中的堆栈跟踪中(您在此处发布)。然后,您需要检查该行上传递给router.use()的每个参数,您会发现问题所在。我们不能为您做到这一点。我告诉你如何找到错误。 -
@jfriend00 我知道哪个中间件是未定义的。但不明白为什么?因为即使这个中间件的编写方式也与其他中间件相同,只是有一些导出常量和导出函数,最后它有
export default router -
@jfriend00 感谢您的回复。我从 A J A Y 的回复中得到了解决。
标签: node.js socket.io mocha.js chai