以記錄開始學習過程中遇到的問題
代碼見:git代碼庫
1.Node-js中exports和module-exports不同
精髓:
1.exports一開始是指向module.exports的;
2.通過require得到的是module.exports中的內容,而不是exports的內容;
// 時髦的寫法:
exports = module.exports = {}
參考:揭祕Node.js中exports和module.exports
2.listen 方法細思
問題:express().listen方法調用 參數和回調函數
參考:ExpressAPI
結論:最終調用的是node裏的Node http模塊 listenAPI
ar express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
var server = app.listen(3000, function () {//listen參考app
/**
server爲什麼可以使用?
因最後一個參數callback會被作爲事件監聽器添加到 'listening'事件
*/
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
express().listen方法調用 具體看Express源碼
/**
* Listen for connections.
*
* A node `http.Server` is returned, with this
* application (which is a `Function`) as its
* callback. If you wish to create both an HTTP
* and HTTPS server you may do so with the "http"
* and "https" modules as shown here:
*
* var http = require('http')
* , https = require('https')
* , express = require('express')
* , app = express();
*
* http.createServer(app).listen(80);
* https.createServer({ ... }, app).listen(443);
*
* @return {http.Server}
* @public
*/
app.listen = function listen() {
var server = http.createServer(this);
return server.listen.apply(server, arguments);//調用Node http模塊
};
由源碼得知調用Node http模塊,因此研究Node 的http模塊
注意:
1.參數requestListener是一個function
2.返回一個服務器對象(可能是http.Server)
3.require()查找模塊路徑問題
1.默認是在“/node-modules”目錄下查找(eg:require(‘express’); 就是查找/node-modules下的文件)
2.“./”是查找當前項目目錄下
4.項目工程化(待)
5.Express 和Node 中間件(待)
Notice: next()別忘記(如果不是阻塞)
1.本質上Express就是Node的中間件集合
2.中間件的回調函數
if(2個||3個參數){
//則頭兩個參數是request和response對象,第3個參數是next函數
}else if(4個參數){
//第一個參數爲Error對象,request,response,next函數
}
3.next處理
if(調用next()){
//一般不易發送相應到客戶端。
}
注意:use 與get/post區別(app.VERB爲特殊是中間件。名詞解釋:app.get/app.post等 通常被稱爲app.VERB)
區別1 app.VERB 第一個參數必須爲path,但普通中間件可以省略
區別2 app.VERB get這些回調函數有可能調用 next(‘route’) 方法而略過其他路由回調函數
6.路由(待)
參考:Express guide
app.route() 其實和掛在app下面具體實現沒有區別
可使用 express.Router 類創建模塊化、可掛載的路由句柄。
Router 實例是一個完整的中間件和路由系統,因此常稱其爲一個 “mini-app”。
在 app 目錄下創建名爲 birds.js 的文件,內容如下:
var express = require('express');
var router = express.Router();
// 該路由使用的中間件
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date.now());
next();
});
// 定義網站主頁的路由
router.get('/', function(req, res) {
res.send('Birds home page');
});
// 定義 about 頁面的路由
router.get('/about', function(req, res) {
res.send('About birds');
});
module.exports = router;
然後在應用中加載路由模塊:
var birds = require('./birds');
...
app.use('/birds', birds);
//應用即可處理髮自 /birds 和 /birds/about 的請求,並且調用爲該路由指定的 timeLog 中間件。
源碼研究:
7.node路徑問題
__filename 和 __dirname 變量是**Node中預定義**的兩個變量。
__filename 獲取當前模塊文件名
__dirname 用於獲取目錄名
//測試:放在路徑 ./test/test.js
console.log('*** app start ***');
console.log('*** module.filename = ' + module.filename + ' ***');
console.log('*** __filename = ' + __filename + ' ***');
console.log('*** __dirname = ' + __dirname + ' ***');
console.log('*** process.cwd() = ' + process.cwd() + ' ***');
console.log('*** require.main.filename= ' + require.main.filename + ' ***');
console.log('*** app end ***');
cd E:\demo\Express\ExpressDemo1\test目錄下,執行 node test
控制檯輸出:
*** app start ***
*** module.filename = E:\demo\Express\ExpressDemo1\test\test.js ***
*** __filename = E:\demo\Express\ExpressDemo1\test\test.js ***
*** __dirname = E:\demo\Express\ExpressDemo1\test ***
*** process.cwd() = E:\demo\Express\ExpressDemo1\test ***
*** require.main.filename= E:\demo\Express\ExpressDemo1\test\test.js ***
*** app end ***
8.靜態資源處理(待)
對於靜態文件處理就是 對於資源文件目錄進行映射
具體映射使用了express.static(root, [options])
reference: Express guide
具體如:
app.use(express.static(__dirname + '/public'));
//notice: Using an absolute address(使用絕對地址,也就是“__dirname ”)