NodeAsp是一套Classic ASP框架,借鉴了NodeJS的模块化思想,让您可以使用全新的理念愉快地书写ASP程序

来源:互联网 发布:武汉纬创纬尊软件 编辑:程序博客网 时间:2024/05/22 10:59

Summary

NodeAsp是一套Classic ASP框架,借鉴了NodeJS的模块化思想,让您可以使用全新的理念愉快地书写ASP程序。

NodeAsp使用遵循CommonJS规范的require,完全兼容NodeJS模块加载方式,让您可以直接使用NodeJS 50%以上的模块。一切不关乎NodeJS运行环境和ES5-ES6特有对象的模块都能直接使用。如此庞大的模块资源库,这在以往任何ASP框架下都是没有的。

NodeAsp是ASP领域独树一帜的创新性框架,她的出现改变了传统的ASP编写模式,让您只需要会js就可以同时完成前后端开发,并免除了部署NodeJS服务器的繁琐过程。

NodeAsp作为ASP领域的终结者,来了。

NodeAsp Runtime

这个框架仅限在WIN平台IIS上运行。通常普通的ASP虚拟主机即可运行本框架。

Start to use nodeAsp

第一步:下载并解压 NodeAsp。

如果您已经安装了nap-cli,那么您可以通过使用命令 nap init 来初始化安装nodeAsp.

第二步:引用 NodeAsp。

<!--#include file="NodeAsp.min.asp" -->

第三步:使用NodeAsp。

<%    var version = process.version;    Response.Write(version);%>

Gobal-Object

这些对象在所有模块中都是可用的。有些对象实际上并非在全局作用域内,而仅仅是在模块作用域内——这种情况在以下文档中会特别指出。

global

在浏览器中,顶级作用域就是全局作用域。这就是说,在浏览器中,如果当前是在全局作用域内,var something将会声明一个全局变量。在NodeAsp中则不同。顶级作用域并非全局作用域,在NodeAsp模块里的var something只属于那个模块。

process

在NodeAsp中,process存在的主要目的是为了兼容某些NodeJS模块,通常不会使用得到。

console

用于打印标准输出和标准错误。见控制台章节。


Buffer

用于处理二进制数据。在ASP环境中,处理二进制通常使用Adodb.Stream,所以我们目前不支持Buffer。

require

引入模块。与NodeJS有点不一样的是,因为IIS只能直接执行ASP文件而非JS文件,所以require也可以用于在ASP代码中require一个模块。

见模块章节。

__filename

当前所执行代码文件的文件路径。这是该代码文件经过解析后的绝对路径。

例如:执行 C:\websites\nodeasp\index.asp

// module.jsResponse.Write(__filename);// C:\websites\nodeasp\module.js// index.asprequire('./module');Response.Write(__filename);// C:\websites\nodeasp\index.asp

__dirname

当前执行脚本所在目录的目录名。

module

当前模块的引用。特别地,module.exports和exports指向同一个对象。module实际上并非全局的而是各个模块本地的。

见模块章节。

exports

module.exports对象的引用,该对象被当前模块的所有实例所共享,通过require()可访问该对象。 何时使用exports以及何时使用module.exports的详情可参见模块系统文档。 exports实际上并非全局的而是各个模块本地的。

见模块章节。

timer

定时器函数一共包括以下四个。由于ASP是单线程的,所以以下函数实际上是不兼容的。

  • setTimeout(cb, ms)
  • clearTimeout(t)
  • setInterval(cb, ms)
  • clearInterval(t)

console api

类似NodeJS/Chrome浏览器的命令行调试模块。请前往下载控制台调试程序。

注意:需要.NET 4.0支持才能运行。

  • 注册COM组件

    以管理员权限打开CMD,使用REGASM命令注册 Terminal.dll,其中REGASM位于C:\Windows\Microsoft.NET\Framework\v4.0.30319(具体位置与版本号有关)。

    // 在命令行执行以下命令,记住需要管理员权限C:\Windows\Microsoft.NET\Framework\v4.0.30319\REGASM D:\component\Terminal.dll /codebase
  • 修改注册表,解决 ASP 0177 : 8000ffff 错误

    对于32位系统,找到如下注册表位置:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_IGNORE_ZONES_INITIALIZATION_FAILURE_KB945701

    对于64位系统,找到如下注册表位置:

    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_IGNORE_ZONES_INITIALIZATION_FAILURE_KB945701

    选择或者新建项 FEATURE_IGNORE_ZONES_INITIALIZATION_FAILURE_KB945701,然后新建DWORD值:

    名称:w3wp.exe 值:1

  • 启动Console

    双击 Console.exe,打开NodeAsp调试命令行工具。

  • 调试

    在index.asp中输入以下代码,然后运行index.asp。接下来,你就可以在 Console.exe中看到结果了。

    // index.aspvar a = {name: "nodeasp", value: true}// 在console中将输出//{//    name: "nodeasp",//    value: true//}

console.log([data][, ...])

向Console输出一个或多个参数的结果,使用默认颜色。

console.info([data][, ...])

同console.log,使用绿色。

console.warn([data][, ...])

同console.log,使用黄色。

console.error([data][, ...])

同console.log,使用红色。

console.time(label)

使用label指定名称,开始一个计时器,用于计算操作所需要花费的时间。

console.timeEnd(label)

输出某项操作所需要消耗的时间。

console.time('100-elements');for (var i = 0; i < 100; i++) {    ;}console.timeEnd('100-elements');// prints 100-elements: 262ms

modules

NodeAsp有一个跟NodeJS几乎一致的模块加载系统,这样可以保证NodeAsp可以直接使用大量NodeJS的模块。

NodeAsp的核心几乎不包含任何开发网站需要功能,所有功能都是通过模块来扩展的。可以通过NodeAsp的模块中心或者npmjs来寻找您所需要的功能模块。

在NodeAsp中,文件和模块是一一对应的。下面是示例foo.js加载同一目录下的circle.js

foo.js的内容

var circle = require('./circle.js');console.log( 'The area of a circle of radius 4 is ' + circle.area(4) );

circle.js的内容:

var PI = Math.PI;exports.area = function (r) {    return PI * r * r;};exports.circumference = function (r) {    return 2 * PI * r;};

circle.js模块输出了area()和circumference()两个函数。要输出某个对象,把它加到exports这个特殊对象下即可。

注意,exports是module.exports的一个引用,只是为了用起来方便。当你想输出的是例如构造函数这样的单个项目,那么需要使用module.exports。

// 正确输出构造函数module.exports = MyConstructor;

模块内的本地变量是私有的。在这个例子中,PI这个变量就是circle.js私有的。

repeat cycle

考虑这样一种情形:

a.js

console.log('a starting');exports.done = false;var b = require('./b.js');console.log('in a, b.done = %j', b.done);exports.done = true;console.log('a done');

b.js

console.log('b starting');exports.done = false;var a = require('./a.js');console.log('in b, a.done = %j', a.done);exports.done = true;console.log('b done');

main.js

console.log('main starting');var a = require('./a.js');var b = require('./b.js');console.log('in main, a.done=%j, b.done=%j', a.done, b.done);

首先main.js加载a.js,接着a.js又去加载b.js。这时,b.js会尝试去加载a.js。为了防止无限的循环,a.js会返回一个unfinished copy给b.js。然后b.js就会停止加载,并将其exports对象返回给a.js模块。

这样main.js就把这两个模块都加载完成了。这段程序的输出如下:

main startinga startingb startingin b, a.done = falseb donein a, b.done = truea donein main, a.done=true, b.done=true

跟NodeJS一样,通常循环依赖模块并不会导致死循环,但是如果此时直接在模块加载时执行其它模块的方法,会提示找不到对应的方法,所以应该避开这种情况。

// a.jsvar b = require('./b.js');    exports.add = function(m, n) {    console.info(m + n);};// b.jsvar a = require('./a');var m = 101, n = 102;exports.result = function() {    a.add(m, n);        // 此处没有问题};a.add(m, n);            // 此处会报错,找不到a.add方法

file module

如果按文件名没有查找到,那么NodeAsp会添加 .js和 .json后缀名,再尝试加载。

.js会被解析为Javascript纯文本文件,.json会被解析为JSON格式的纯文本文件。

模块以/为前缀,则表示绝对路径。例如,require('/home/marco/foo.js') ,加载的是/home/marco/foo.js这个文件。

模块以./为前缀,则路径是相对于调用require()的文件。 也就是说,circle.js必须和foo.js在同一目录下,require('./circle')才能找到。

当没有以/或者./来指向一个文件时,这个模块是从node_modules文件夹加载的。

如果指定的路径不存在,require()会抛出一个错误。

load from node_modules

如果require()中的模块名不是一个本地模块,也没有以/../, 或是 ./开头,那么node会从当前模块的父目录开始,尝试在它的/node_modules文件夹里加载相应模块。

如果没有找到,那么就再向上移动到父目录,直到到达顶层目录位置。

例如,如果位于/home/ry/projects/foo.js的文件调用了require('bar.js'),那么node查找的位置依次为:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

这就要求程序员应尽量把依赖放在就近的位置,以防崩溃。

module package

可以把程序和库放到一个单独的文件夹里,并提供单一入口来指向它。有三种方法,使一个文件夹可以作为require()的参数来加载。

首先是在文件夹的根目录创建一个叫做package.json的文件,它需要指定一个main模块。下面是一个package.json文件的示例。

{    "name" : "some-library",    "main" : "./lib/some-library.js"}

示例中这个文件,如果是放在./some-library目录下面,那么require('./some-library')就将会去加载./some-library/lib/some-library.js

如果目录里没有package.json这个文件,那么node就会尝试去加载这个路径下的index.js

cache

模块在第一次加载后会被缓存。这意味着(类似其他缓存)每次调用require('foo')的时候都会返回同一个对象,当然,必须是每次都解析到同一个文件。

多次调用 require(foo) 未必会导致模块中的代码执行多次. 这是一个重要的功能. 借助这个功能, 可以返回部分完成的对象; 这样, 传递依赖也能被加载, 即使它们可能导致循环依赖。

如果你希望一个模块多次执行,那么就输出一个函数,然后调用这个函数。

模块的缓存是依赖于解析后的文件名。由于随着调用的位置不同,可能解析到不同的文件(比如需从node_modules文件夹加载的情况),所以,如果解析到其他文件时,就不能保证require('foo')总是会返回确切的同一对象。

module object

在每一个模块中,变量 module 是一个代表当前模块的对象的引用。 特别地,module.exports 可以通过全局模块对象 exports 获取到。 module 不是事实上的全局对象,而更像是每个模块内部的。

module.exports

module.exports对象是通过模块系统产生的。因此,只需要将要导出的对象赋值给module.exports。例如,我们也可以使用下面的方法来写circle.js,这是完全等效的。

// circle.jsvar PI = Math.PI;var circle = {};circle.area = function (r) {    return PI * r * r;};circle.circumference = function (r) {    return 2 * PI * r;};module.exports = circle;

module.id

用于区别模块的标识符。通常是完全解析后的文件名。

module.filename

模块完全解析后的文件名。

module.parent

引入这个模块的模块。

search process

当使用require()引用一个模块时,是按照如下流程根据表达式来查找目标模块的。

require(X) from module at path Y1. If X begins with './' or '/' or '../'a. LOAD_AS_FILE(Y + X)b. LOAD_AS_DIRECTORY(Y + X)2. LOAD_NODE_MODULES(X, dirname(Y))3. THROW "not found"LOAD_AS_FILE(X)1. If X is a file, load X as JavaScript text.  STOP2. If X.js is a file, load X.js as JavaScript text.  STOP3. If X.json is a file, parse X.json to a JavaScript Object.  STOPLOAD_AS_DIRECTORY(X)1. If X/package.json is a file,a. Parse X/package.json, and look for "main" field.b. let M = X + (json main field)c. LOAD_AS_FILE(M)2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOPLOAD_NODE_MODULES(X, START)1. let DIRS=NODE_MODULES_PATHS(START)2. for each DIR in DIRS:a. LOAD_AS_FILE(DIR/X)b. LOAD_AS_DIRECTORY(DIR/X)NODE_MODULES_PATHS(START)1. let PARTS = path split(START)2. let I = count of PARTS - 13. let DIRS = []4. while I >= 0,a. if PARTS[I] = "node_modules" CONTINUEc. DIR = path join(PARTS[0 .. I] + "node_modules")b. DIRS = DIRS + DIRc. let I = I - 15. return DIRS

0 0