NodeJS独立开发web框架——静态服务器开发(4)
打造web框架雏形
在这一节中,要让先前的代码形成一个模块,这个模块名就叫stuwebfk。
我们在stuwebfk项目目录下,建立一个lib文件夹,里面创建一个App.js文件,然后把先前的代码整合到其中。
// App.js 文件,该文件表示应用程序类
function App(){ }
module.exports = App; // 这是模块出口,这样外界才能访问到App类。这就是一个简单模块,当外界可以通过 var App = require("./lib/App")的方式得到App类,当然要看访问文件本身的位置,比如都在lib一个目录内,那么可以用var App = require("./App")得到App类。
小胖问道:我有个疑惑,比如为什么
fs和http模块的引用,不用require("./fs"),而直接用require("fs")就可以访问到呢?
这个问题提的很好,看你来你的观察力很强!这个问题我不想一次性说透,我们还是以项目为驱动的去学习,既然你问到了,我简单的先说一下,过几天随着项目的进展,不用大篇幅的介绍其概念,你也就理解了。学习的最好方式是去模仿,通过项目的进展你会从根本上领悟。
node.js中,可通过多种方式require到相应的模块,node.js核心的API,可通过require(模块名)的方式访问到,如果把模块放在node_modules目录中,那么该目录的同级目录,和同级目录下的子目录内的JS程序,都可通过 require(模块名)的方式访问到,下图显示了这种关系。
这里的aaa和bbb目录内JS程序,和当前目录的a.js都可以通过require(模块名)的方式访问到node_modules目录下的模块。这个问题暂时就介绍到这里。
App代表一个应用的概念,通过var app = new App()的方式可以创建一个应用,这样就脱离开了底层的一些概念,也就是通过封装的方式,让开发更人性化。
下面写一段为代码,代替先前使用底层代码。
var webfk = require("stuwebfk");
var app = new webfk.App();
app.use(webfk.static(__dirname+"/public")); // 通过插件的方式加入静态服务器的功能
app.listen(3000);上面这段代码还没有实现,眼下只是个蓝图,下面就一步步的加以实现。我们要在项目根目录下,建立如下的文件。
App.js 是应用程序类,通过new App可以创建一个应用程序。
static.js 是静态资源服务的中间件,其实之前的代码主要是加入这个文件中,作为一个插件形式存在。
index.js 是整个模块的出口,这样就可以通过 require("stuwebfk").App 和 require("stuwebfk").static 访问了。
下面列出三个文件的实现代码,看起来很害怕,今天不会深入研究这些具体实现,只要简单了解一下即可,后面几天会深入剖析具体的实现方式。
lib/static.js 文件内容
var url = require("url"),
fs = require("fs");
// 把URL转换成资源路径
function url2path(url_str){
var urlObj = url.parse(url_str);
var path = urlObj.path;
return path;
}
module.exports = function static(parent_path){
return function(req,res,next){ // 这个插件无需调用next。
var path = url2path(req.url);
function callback(err,data){
if(err){
res.statusCode = 404;
}
else
res.write(data);
res.end();
}
fs.readFile(parent_path+path,callback);
}
}lib/App.js 文件内容
var http = require("http");
module.exports = App;
function App(){
// 插件有序列表
var middleList = this._middleList = [];
// request事件响应函数
function handle(req,res){
if(middleList.length === 0){
// 如果没有功能插件什么都不做。
}else{
// 循环执行插件
var middleIndex = 0; // 插件索引
execMiddle();
// 执行这个函数时,会自动执行下一个middle插件。
// 至于这个函数的执行,是由插件所控制。
function next(){
middleIndex += 1;
execMiddle();
}
// 执行插件函数
function execMiddle(){
var middle = middleList[middleIndex];
if(middle){
middle(req,res,next);
}
}
}
}
this._server = http.createServer(handle);
}
// 加入功能栈
App.prototype.use = function(middle){
this._middleList.push(middle);
}
// 监听端口
App.prototype.listen = function(){
this._server.listen.apply(this._server,arguments);
}index.js 文件内容
exports.App = require("./lib/App");
exports.static = require("./lib/static");今天项目的进展很大,形成了一个雏形框架,通过今天的实战会有很多收获,也会有很多疑惑,这都是进步。在以项目为驱动的学习过程中,重点不是记住多少知识,而是去体悟那种开发的感觉,还是那句话,知识是可以学到的,经验只能被传授。传授的意思就是通过具体项目的实践,在模仿的过程中,逐步形成自己的体悟,也就是经验。
明天将会具体剖析stuwebfk框架的实现方式。今天就到这里,祝你好梦!
所有文章未经授权禁止转载、摘编、复制或建立镜像,违规转载法律必究。
举报邮箱:doramart@qq.com
推荐阅读
微信客服
微信公众号