我正在尝试将 NodeJS 模块(constant xxx = require('yyy'))重写为 es6 格式。我尝试在 es6 中使用
export
语法导出路由器,但总是弹出以下错误:
throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
^
TypeError: Router.use() requires a middleware function but got a Module
at Function.use (C:\Users\blog\node_modules\express\lib\router\index.js:469:13)
at Function.<anonymous> (C:\Users\blog\node_modules\express\lib\application.js:227:21)
at Array.forEach (<anonymous>)
at Function.use (C:\Users\blog\node_modules\express\lib\application.js:224:7)
at file:///C:/Users/blog/server.js:20:5
at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:28:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)
我确信我的 es6 语法应该是正确的:
export default router;
可能与此错误相关的代码如下:
路线/article.js
import express from 'express'
import * as Article from './../models/article.js';
const router = express.Router()
router.get('/new', (req, res) => {
res.render('article/new', { article: new Article() })
})
router.get('/edit/:id', async (req, res) => {
const article = await Article.findById(req.params.id)
res.render('article/edit', { article: article })
})
router.get('/:slug', async (req, res) => {
const article = await Article.findOne({ slug: req.params.slug })
if (article == null) res.redirect('/')
res.render('article/show', { article: article })
})
router.post('/', async (req, res, next) => {
req.article = new Article()
next()
}, saveArticleAndRedirect('new'))
router.put('/:id', async (req, res, next) => {
req.article = await Article.findById(req.params.id)
next()
}, saveArticleAndRedirect('edit'))
router.delete('/:id', async (req, res) => {
await Article.findByIdAndDelete(req.params.id)
res.redirect('/')
})
function saveArticleAndRedirect(path) {
return async (req, res) => {
let article = req.article
article.title = req.body.title
article.description = req.body.description
article.markdown = req.body.markdown
try {
article = await article.save()
res.redirect(`/article/${article.slug}`)
} catch (e) {
res.render(`article/${path}`, { article: article })
}
}
}
export default router;
其他可能相关的代码:
模型/article.js
import mongoose from 'mongoose'
import {marked} from 'marked'
import slugify from 'slugify'
import createDomPurify from 'dompurify'
import { JSDOM } from 'jsdom'
const dompurify = createDomPurify(new JSDOM().window)
const articleSchema = new mongoose.Schema({
title:{
type: String,
required: true
},
description: {
type: String
},
markdown: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
},
slug: {
type: String,
required: true,
unique: true
},
sanitizedHTML: {
type: String,
required: true
}
})
articleSchema.pre('validate', function(next) {
if(this.title) {
this.slug = slugify(this.title, {lower: true, strict:true})
}
if(this.markdown){
this.sanitizedHTML = DomPurify.sanitize(marked.parse(this.markdown))
}
else{
console.log("Error")
}
next()
})
export const Article = mongoose.model('Article', articleSchema);
服务器.js:
import express from 'express'
import mongoose from 'mongoose'
import * as Article from './models/article.js';
import * as articleRouter from './route/article.js';
import methodOverride from 'method-override'
const app = express()
mongoose.connect('mongodb://localhost:27017/', {})
app.set('view engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.use(methodOverride('_method'))
app.get('/', async (req, res) => {
const article = await Article.find().sort({ createdAt: 'desc' })
res.render('article/index', { article: article })
})
app.use('/article', articleRouter)
app.listen(3000)
文件结构如下:
问题出在你的
import * as articleRouter from './route/article.js';
。
您的
article.js
文件除了默认导出 (router
) 之外不导出任何内容。这就是您发现此错误的原因。
如果您想保留
use
,您也可以尝试 articleRouter.default
-ing import * as...
,但这显然是一个不好的做法。
import express from 'express'
import mongoose from 'mongoose'
import * as Article from './models/article.js';
import articleRouter from './route/article.js';
import methodOverride from 'method-override'
const app = express()
mongoose.connect('mongodb://localhost:27017/', {})
app.set('view engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.use(methodOverride('_method'))
app.get('/', async (req, res) => {
const article = await Article.find().sort({ createdAt: 'desc' })
res.render('article/index', { article: article })
})
app.use('/article', articleRouter)
app.listen(3000)