前言
调试
node.js
的报错,不是很直观,因为它通常是模块级的报错,排查这种错误需要的是开发经验的积累。在 node.js 中,require , exports, module
属于比较重要的概念
require 的用法:
引用 'http' 模块: require('http')
./ 表示当前路径,后面跟的是相对路径 : require('./server')
../ 表示上一级目录,后面跟的也是相对路径:require("../lib/server")
在这次课堂上,同学们按照我给的课件,一边敲击代码一边运行调试。 原本进展很顺利,不巧被一个报错带来了困惑。 报错信息如下:
myShop/node_modules/express/lib/router/index.js:458
throw new TypeError('Router.use() requires middleware function but got a ' + gettype(fn));
^
TypeError: Router.use() requires middleware function but got a Object
at Function.use (/myMac/01_MEAN/01-1-NCUT/20171213/02-code/myShop/node_modules/express/lib/router/index.js:458:13)
如果把这种错误放在网上去搜,搜出来的结果五花八门。 这种错误太抽象了,很难排查。
仔细查看,推测是在app.use 上出了错误,它时由 Router.use() 引发的。 顺藤摸瓜!
工程中有这样一行代码,与router 相关:
app.use('/api/goods', require('./routes/goods'));
从中看,没有明显的书写错误。看起来正常。 这说明问题出在 goods.js 文件的引用上。
如果把上面这行代码分解为两行,会更加简洁易懂:
var goods = require('./routes/goods');
app.use('/api/goods', goods);
代码解读: require('./routes/goods');
引用了一个module ,返回了一个对象。
以上报错说明,module 的引用出了问题。
再来看 goods.js 这个module, 为了该模块被引用,在它的最后,应该有这样的一行代码: module.exports = .....
通过一步步排查发现, good.js 文件的最后,没有module.exports 这行代码。
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Goods = require('../models/model_goods.js');
/* GET Request */
router.get('/', function(req, res, next) {
Goods.find(function (err, data) {
if (err) return next(err);
res.json(data);
});
});
//....
module.exports = router;
小结
-
每个模块(module)都会自动创建一个 module 对象,同时 module 对象会创建一个叫 exports的属性,初始化的值是{ }。 这就是说, module.exports 初始值为一个空对象 {}。
-
require() 返回的是 module.exports 。 从中可以看书,
module.exports
是多么重要,如果漏写了module.exports
,require
的返回值就失去了意义。 -
事实上,每个module文件的最后,都应该至少有一个
module.exports
,否则的话,创建这个moudle 又有什么意义呢! -
对于创建的express 工程来说, 即便是 app.js 文件的最后,都有一行
module.exports
module.exports = app;
网友评论