分享一個基於 Node.js 的 Web 開發框架 - Nokitjs

簡介

Nokit 是一個簡單易用的基於 Nodejs 的 Web 開發框架,默認提供了 MVC / NSP / RESTful 等支持,並提供對應項目模板、管理工具。javascript

資源

安裝和更新

安裝 nokit

[sudo] npm install nokitjs [-g]

更新 nokit

[sudo] npm update nokitjs [-g]

命令行工具

使用 「命令行工具」 時必須全局安裝 nokitjs (全局安裝的同時也能夠在 app 中本地安裝 nokitjs),Nokit 應用只需在磁盤創建應用目錄,並新建相關文件和目錄便可, Nokit 提供了方便的命令行工具。linux

命令行工具還提供了進程管理相關功能,確保應用可以持續穩定的運行,並能在遇到故障時快速自動恢復。git

查看版本

[sudo] nokit [?]

建立應用

[sudo] nokit create [name] [mvc|nsp|restful] [folder]

以上命令會生成一個最簡單的應用所須要的目錄結構和配置。github

  1. name 通常不建議省略(省略時爲 nokit-app),name 將會做爲應用的根目錄名稱正則表達式

  2. type 默認爲 mvc 也能夠指定爲 nsp 或 restful ,指定類型後將會建立對應的應用模板npm

  3. folder 爲目標目錄,省略時將默認爲當前所在目錄。

運行應用

[sudo] nokit start [port] [root] [-env:<name>] [-cluster[:num]] [-watch[:.ext,...]] [node-opts]
  1. -env 指定運行配置名稱,將會根據 "配置名稱" 加載 app.xxx.json (xxx 爲指定的配置名稱) 做爲應用配置文件。

  2. -cluster 選項能夠開啓 "單機集羣模式",使應用有效的利用多核 CPU,也使應用更加健壯可靠,-cluster 選項能夠指定進程數,如 -cluster:4 ,默認爲 CPU 核數。

  3. -watch 選項開啓後,在應用文件發生改變時會自動完成進程重啓,默認任何文件變動都將觸發重啓,也能夠指定文件類型,如 -watch:.js,.html,.css

  4. -public 通常用於爲 html/js/css 等靜態資源啓動一個臨時 WebServer,指定靜態資源目錄,靜態資源目錄爲 root 的相對目錄。

  5. -cache 通常用於爲 html/js/css 等靜態資源啓動一個臨時 WebServer,指定緩存配置,例如 -cache:0 不向瀏覽器發送緩存 header 信息。

  6. --debug 爲 nodejs 選項,能夠開啓 debug 模式,開啓後可使用 nodejs 內置調試工具調式,也可使用 node-inspector 等工具進行調試。

中止應用

[sudo] nokit stop [pid|all]

能夠指定 pid (進程ID,能夠用過 nokit list 查看),中止指定的的應用,也能夠省略中止全部應用

重啓應用

[sudo] nokit restart [pid|all]

能夠指定 pid (進程ID,能夠用過 nokit list 查看),重啓指定的的應用,也能夠省略重啓全部應用

查看運行中的應用

[sudo] nokit list

查看全部已啓動的應用

開機自啓動

[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 時所用的帳戶。

在代碼中引用

除了使用命令行工具,也能夠在代碼中引用 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 (還未所有開發完畢)

NSP

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();
};

MVC

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"
        }]
    }
}

RESTful

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 能夠在請求的不一樣階段截獲請求,進行相關邏輯處理後,繼續向下處理請求或結束請求,一個完整的 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"
    }
}
相關文章
相關標籤/搜索