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


簡介

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

資源

安裝和更新

安裝 nokit

[sudo] npm install nokitjs [-g]

更新 nokit

[sudo] npm update nokitjs [-g]

命令行工具

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

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

查看版本

[sudo] nokit [?]

創建應用

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

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

  1. name 一般不建議省略(省略時為 nokit-app),name 將會作為應用的根目錄名稱
  2. type 默認為 mvc 也可以指定為 nsp 或 restful ,指定類型后將會創建對應的應用模板
  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 的進程管理功能,這時可以直接運行,或者使用 pm2、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"
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM