Nokit 是一个简单易用的基于 Nodejs 的 Web 开发框架,默认提供了 MVC / NSP / RESTful 等支持,并提供对应项目模板、管理工具。javascript
- GitHub https://github.com/nokitjs/nokit (
欢迎 star、fork
)- 使用说明 wiki
- 问题反馈 issues
- 主页 http://nokit.org
[sudo] npm install nokitjs [-g]
[sudo] npm update nokitjs [-g]
使用 “命令行工具
” 时必须全局
安装 nokitjs (全局安装的同时也能够在 app 中本地安装 nokitjs),Nokit 应用只需在磁盘创建应用目录,并新建相关文件和目录便可, Nokit 提供了方便的命令行工具。css
命令行工具还提供了进程管理相关功能,确保应用可以持续稳定的运行,并能在遇到故障时快速自动恢复。html
[sudo] nokit [?]
[sudo] nokit create [name] [mvc|nsp|restful] [folder]
以上命令会生成一个最简单的应用所须要的目录结构和配置。java
[sudo] nokit start [port] [root] [-env:<name>] [-cluster[:num]] [-watch[:.ext,...]] [node-opts]
[sudo] nokit stop [pid|all]
能够指定 pid (进程ID,能够用过 nokit list 查看),中止指定的的应用,也能够省略中止全部应用node
[sudo] nokit restart [pid|all]
能够指定 pid (进程ID,能够用过 nokit list 查看),重启指定的的应用,也能够省略重启全部应用linux
[sudo] nokit list
查看全部已启动的应用git
[sudo] nokit autostart [on|off] [-uid:[domain\]user [-pwd:password]]
autostart 命令目前支持 win32 和 linux 平台,此命令须要管理员权限,如 ubuntu 须要使用 sodu
, 在 windows 平台会弹出 "用户帐户控制" 提示框。 -uid 和 -pwd 参数仅在 win32 平台有效,其它平台将被忽略,在不指定 -uid 、-pwd 参数时,需有用户登陆到 windows 才会自动启动 Nokit App,当指定 -uid、-pwd 时,只要启动 windows 就会自动启动 Nokit App。 不管是登陆 windows 的帐户或是经过 -uid 提定的帐户,须要是安装 nodejs 和 npm 时所用的帐户。github
除了使用命令行工具,也能够在代码中引用 nokit 的方式来运行 nokit 应用, 在代码中引用 nokit,将不能利用 nokit 的进程管理功能,这时能够直接运行,或者使用 pm二、forever 等工具进行管理。正则表达式
var nokit = require("nokitjs"); var server = new nokit.Server({ root : "应用根目录", port : 8000 }); server.start();
不管任种方式,启动成功后,便可浏览器访问 "http://localhost:8000" (端口请换成具体应用的正确的端口), 示例站点 http://jser.cc (还未所有开发完毕)npm
NSP 全称为 Nokit Server Pages
是一种相似 asp / asp.net
的 Web 应用开发模式, NSP 支持 include 引用其它页面,也支持 master 母板页
技术。
通常目录结构
根目录 │ app.json │ app.js ├─layout │ date.nsp │ master.nsp ├─model └─public │ index.nsp │ index.nsp.js └─style common.css
NSP 页面 (*.nsp) 基本介绍
输出内容
<p> <%= "输出内容" %> </p> <!-- this 指向页面处理器,无处理器页面指向默认处理器对象 --> <p> <%= this.context.request.formData("name") %> </p>
循环
<ul> <% $.each(this.list,function(i,item){ %> <li><%= item.name %></li> <% }) %> </ul>
分支
<% if(this.type=='a'){ %> <span>a</span> <% }else{ %> <span>b</span> <% } %>
包含
<% $.include("../layout/head.nsp") %>
母板页(Master Page
)
<html> ... <div> <% $.placeHolder("content1") %> </div> ... <div> <% $.placeHolder("content2") %> </div> ... </html>
内容页(Content Page
)
<% $.master("./master.nsp") %> <% $.placeBegin("content1") %> <span>content1</span> <% $.placeEnd() %> <% $.placeBegin("content2") %> <span>content2</span> <% $.placeEnd() %>
NSP 页面处理器 (*.nsp.js) 基本介绍
//定义页面处理器类型 var IndexPresenter = module.exports = function() {}; //初始化方法,每次回发都将触发 init 方法 IndexPresenter.prototype.init = function() { var self = this; /* self.server //当前 server 实例 self.context //当前请上下文对象 self.request //同 context.request,请求对象 self.response //同 context.response 响应对象 self.context.request.queryData['name'] 能够获取 queryString 对应数据 self.context.request.formData['name'] 能够获取 post 数据 self.context.data("name") 能够获取客户端传过来的 queryString 或 formData self.context.request.cookie 获取来自客户的 cookie self.context.respone.cookie 向客户端发送 cookie se轩.context.session 访问 session 数据 */ self.name = 'Nokit NSP'; //init(初始化)完成后,须要调用 ready 方法,通知初始化完成 self.ready(); }; //默认方法,首次打开页面,会触发 load 方法 IndexPresenter.prototype.load = function() { var self = this; //因为 nokit 为异步处理,调用 self.render() 方法向浏览器呈现页面. //不要在 init 方法调用 self.render() self.render(); }; //事件方法,能够绑定到页面中的 html 控件 IndexPresenter.prototype.add = function() { var self = this; var val = parseInt(self.numBox.val()); self.numBox.val(++val); self.numBox.css("border","solid 1px red"); self.render(); };
页面绑定
<!-- 绑定处处理器方法 --> <input type="button" onclick="nsp.call('add')" value='add' />
共享元素
,将普通 DOM 元素经过 "nsp-id
" 声明为客户端和服务端的共享元素,即可以在客户端和服务端同时操做指定元素, 并能在回发时保持状态,相似 Asp.NET 的 WebForms,但理念、原理又很是不一样,NSP 共享元素很是轻量,更简洁易用。
<!-- 此元素能够在服务端和客户端同时访问 --> <input type="text" value="hello" nsp-id='test' />
Index.prototype.add = function() { var self = this; //服务端提供类 jQuery 的元素操做 API (兼容部分经常使用 jQUery API) self.test.val('你好'); self.render(); };
Nokit MVC 是一种设计简约、符合 MVC 模式 Web 应用开发模式。
通常目录结构
根目录 │ app.json │ app.js ├─controllers │ home.js ├─models ├─public │ └─style │ common.css └─views date.html home.html master.html
views 目录存放的是视图,视图和 NSP 的页面类似,支持 include 和 master,语法也彻底相同, 不一样的是在 mvc 的视图中
this
指向的是模型,视图具备单一的责职 ,就是呈现模型中的数据。
controllers 是控制器目录,单个文件为一个控制器,用来响应接受来自用户的请求,并传递给模型, 而后,完成模型和视图的装配。 models 为模型目录,nokit 对模型没有统一的要求和控制,应用的业务逻辑应在模型中完成。
MVC 的控制器示例
//定义控制器类型 var HomeController = module.exports = function() {}; /* 默认 action , 一般用户直接请求某一 url 会被路由到指定 controller 的默认 action */ HomeController.prototype.index = function() { var self = this; /* self.context 能够访问当前请求上下文对象 self.context.routeData["name"] 能够获取路由数据 self.context.request.queryData['name'] 能够获取 queryString 对应数据 self.context.request.formData['name'] 能够获取 post 数据 self.context.data("name") 能够获取客户端传过来的 queryString 或 formData self.context.request.cookie 获取来自客户的 cookie self.context.respone.cookie 向客户端发送 cookie se轩.context.session 访问 session 数据 */ //经过 self.render 方法呈现指定的视图,并进行模型绑定 self.render("home.html", { "name": "Nokit MVC" }); };
MVC 的 app.json 配置
{ /* 配置 handler ,将指定的请求交由 MVC Handler 处理,支持正则表达式, 如示例,将应用的全部请求都交由 MVC 处理, 在找不到匹配的路由配置时,会转由 Static Handler 处理 */ "handlers": { "^/": "$./handlers/mvc" }, "mvc": { /* 配置 MVC 相关代码文件的存放目录,指定 controller 和 view 的目录位置, model 不用配置。 */ "paths": { "controller": "./controllers", "view": "./views" }, /* 每个路由至少须要指定 pattern(URL匹配模式) 和 target(目标contrller) 还能够经过配置 action 项指定对应的 action (controller方法)。 pattern 格式示例 "/user/{userId}" 其中 userId 是占位符变量, 能够在 controller 中经过 context.routeData['userId'] 获取。 */ "routes": [{ "pattern": "/home", "target": "./home.js" },{ "pattern": "/", "target": "./home.js" }] } }
Nokit 用来开发 RESTful Service 是很是方便和简单的,经过简洁的 URL 路由配置,抽象出和资源对应的请求处理程序文件便可, 能够在处理程序中,根据需求实现 get / post / put 等 HttpMethod 便可。
通常目录结构
根目录 │ app.json │ app.js ├─public │ │ index.nsp │ └─style │ common.css └─restful user.js
REST 的资源控制器示例
//定义资源控制器类型,一般一个资源类型视为一个控制器 function HelloController() {}; /** * post 处理方法 **/ HelloController.prototype.post = function () { var self = this; /* self.context 能够访问当前请求上下文对象 self.context.routeData["name"] 能够获取路由数据 self.context.request.queryData['name'] 能够获取 queryString 对应数据 self.context.request.formData['name'] 能够获取 post 数据 self.context.data("name") 能够获取客户端传过来的 queryString 或 formData self.context.request.body 能够访问请求的主体对象 */ self.out({ "status": "success", "message": "Hello " + self.context.routeData["name"] + "!" }); }; /** * get 处理方法 **/ HelloController.prototype.get = function () { var self = this; self.out({ "status": "success", "message": "Hello " + self.context.routeData["name"] + "!" }); };
REST 的 app.json 配置
{ /* 配置 handler ,将指定的请求交由 REST Handler 处理,支持正则表达式, 如示例,/api/... 开头的请求,交由 REST Handler 处理 */ "handlers": { "^/api/": "$./handlers/restful" }, "restful": { "path": "./restful", //指定资源控制器的存放目录 /* 每个路由至少须要指定 pattern(URL匹配模式) 和 target(目标contrller) pattern 格式示例 "/user/{userId}" 其中 userId 是占位符变量, REST 的路由配置没有 action 配置项。 */ "routes": [{ "pattern": "/api/hello/{name}", "target": "./hello" }] } }
Filter 能够在请求的不一样阶段截获请求,进行相关逻辑处理后,继续向下处理请求或结束请求,一个完整的 filter 包括 4 个事件,以下
//定义一个 Filter function DemoFilter(){} //在请求开始时 DemoFilter.prototype.onRequestBegin = function (context, next) { next(); }; //在收到数据时 DemoFilter.prototype.onReceived = function (context, next) { next(); }; //在向客户端响应内容时 DemoFilter.prototype.onResponse = function (context, next) { next(); }; //在请求即将结束时 DemoFilter.prototype.onRequestEnd = function (context, next) { next(); };
在应用中注册 Filter,在 应用配置 app.json
中配置:
{ "filters":{ "^/":"./filters/demo-filter.js" } }