{"id":21428670,"url":"https://github.com/spikef/nodeasp","last_synced_at":"2025-06-14T03:37:40.616Z","repository":{"id":57311849,"uuid":"44656471","full_name":"Spikef/NodeAsp","owner":"Spikef","description":"A JavaScript runtime built on classic asp. It works like NodeJS.","archived":false,"fork":false,"pushed_at":"2016-05-04T14:31:38.000Z","size":210,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-07T21:20:37.954Z","etag":null,"topics":["asp","jscript","nodejs"],"latest_commit_sha":null,"homepage":null,"language":"ASP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Spikef.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-21T06:16:55.000Z","updated_at":"2024-06-27T09:27:02.000Z","dependencies_parsed_at":"2022-09-10T22:11:32.626Z","dependency_job_id":null,"html_url":"https://github.com/Spikef/NodeAsp","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2FNodeAsp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2FNodeAsp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2FNodeAsp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Spikef%2FNodeAsp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Spikef","download_url":"https://codeload.github.com/Spikef/NodeAsp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225970900,"owners_count":17553410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp","jscript","nodejs"],"created_at":"2024-11-22T22:14:19.338Z","updated_at":"2024-11-22T22:14:20.057Z","avatar_url":"https://github.com/Spikef.png","language":"ASP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NodeAsp #\r\n\r\n`NodeAsp`是一套Classic ASP框架，借鉴了NodeJS的模块化思想，让您可以使用全新的理念愉快地书写ASP程序。\r\n\r\n`NodeAsp`使用遵循CommonJS规范的require，完全兼容NodeJS模块加载方式，让您可以直接使用NodeJS 50%以上的模块。一切不关乎NodeJS运行环境和ES5-ES6特有对象的模块都能直接使用。如此庞大的模块资源库，这在以往任何ASP框架下都是没有的。\r\n\r\n`NodeAsp`是ASP领域独树一帜的创新性框架，她的出现改变了传统的ASP编写模式，让您只需要会js就可以同时完成前后端开发，并免除了部署NodeJS服务器的繁琐过程。\r\n\r\n`NodeAsp`作为ASP领域的终结者，来了。\r\n\r\n## 主页 ##\r\n\r\nNodeAsp：http://nodeasp.com\r\n\r\n模块下载：http://nap.webkits.cn\r\n\r\n## 运行环境 ##\r\n\r\n这个框架仅限在WIN平台IIS上运行。通常普通的ASP虚拟主机即可运行本框架。\r\n\r\n## 简单示例 ##\r\n\r\ndefault.asp\r\n\r\n```asp\r\n\u003c!--#include file=\"NodeAsp.asp\" --\u003e\r\n\r\n\u003c%\r\n    require('./index.js');\r\n%\u003e\r\n```\r\n\r\nindex.js\r\n\r\n```javascript\r\nvar http = require('http');\r\n\r\nhttp.createServer(function(req, res){\r\n  res.writeHead(200, {'Content-Type': 'text/plain'});\r\n  res.end('Hello World\\n');\r\n});\r\n```\r\n\r\n## 使用方法 ##\r\n\r\n第一步：下载NodeAsp。\r\n\r\n第二步：引用NodeAsp。\r\n\r\n```html\r\n\u003c!--#include file=\"NodeAsp.min.asp\" --\u003e\r\n```\r\n\r\n第三步：使用NodeAsp。\r\n\r\n```html\r\n\u003c%\r\nvar version = process.version;\r\nResponse.Write(version);\r\n%\u003e\r\n```\r\n\r\n## 全局对象 ##\r\n\r\n这些对象在所有模块中都是可用的。有些对象实际上并非在全局作用域内，而仅仅是在模块作用域内——这种情况在以下文档中会特别指出。\r\n\r\n### global ###\r\n\r\n在浏览器中，顶级作用域就是全局作用域。这就是说，在浏览器中，如果当前是在全局作用域内，var something将会声明一个全局变量。在NodeAsp中则不同。顶级作用域并非全局作用域，在NodeAsp模块里的var something只属于那个模块。\r\n\r\n### process ###\r\n\r\n输出与运行环境有关的一些信息。\r\n\r\n在NodeAsp中，process存在的主要目的是为了兼容某些NodeJS模块，通常不会使用得到。\r\n\r\n### console ###\r\n\r\n用于打印标准输出和标准错误。\r\n\r\n详见下面的`控制台`章节。\r\n\r\n### Buffer ###\r\n\r\n我们引入了buffer模块来兼容NodeJS的Buffer，请注意必须在node_modules下包含buffer模块才能使用Buffer。\r\n\r\n如果您忘记在node_modules下放入buffer模块，这并不会影响程序的正常运行，只有当您使用Buffer时，才会抛出错误。\r\n\r\n### require ###\r\n\r\n引入模块。与NodeJS有点不一样的是，因为IIS只能直接执行ASP文件而非JS文件，所以require也可以用于在ASP代码中require一个模块。类似于在命令行中执行node test.js。\r\n\r\n如果想知道调用require()方法加载模块时的真实文件路径，可以使用require.resolve()方法来得到。\r\n\r\n详见下面的`模块`章节。\r\n\r\n### __filename ###\r\n\r\n当前所执行代码文件的文件路径。这是该代码文件经过解析后的绝对路径。\r\n\r\n例如：执行 C:\\websites\\nodeasp\\index.asp\r\n\r\n```javascript\r\n// module.js\r\nResponse.Write(__filename);\r\n// C:\\websites\\nodeasp\\module.js\r\n\r\n// index.asp\r\nrequire('./module');\r\nResponse.Write(__filename);\r\n// C:\\websites\\nodeasp\\index.asp\r\n```\r\n\r\n### __dirname ###\r\n\r\n当前执行脚本所在目录的目录名。\r\n\r\n### module ###\r\n\r\n当前模块的引用。特别地，module.exports和exports指向同一个对象。module实际上并非全局的而是各个模块本地的。\r\n\r\n详见下面的`模块`章节。\r\n\r\n### exports ###\r\n\r\nmodule.exports对象的引用，该对象被当前模块的所有实例所共享，通过require()可访问该对象。 何时使用exports以及何时使用module.exports的详情可参见模块系统文档。 exports实际上并非全局的而是各个模块本地的。\r\n\r\n详见下面的`模块`章节。\r\n\r\n### 定时器 ###\r\n\r\n定时器函数一共包括以下四个。由于ASP是单线程的，所以以下函数实际上是不兼容的。\r\n\r\n    setTimeout(cb, ms)\r\n\r\n    clearTimeout(t)\r\n\r\n    setInterval(cb, ms)\r\n\r\n    clearInterval(t)\r\n\r\n## 控制台 ##\r\n\r\n为了更好的调试ASP程序，我们实现了类似NodeJS/Chrome浏览器的命令行调试工具。下载地址：https://github.com/Spikef/NodeAsp-Console\r\n\r\n\u003e NOTE: 需要IIS7.5和.NET4才能运行，其它环境未测试。\r\n\r\n### 使用指南 ###\r\n\r\n#### 第一步：注册COM组件 ####\r\n\r\n以管理员权限打开CMD，使用REGASM命令注册component\\Terminal.dll，其中REGASM位于C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319(具体位置与版本号有关)。\r\n\r\n```\r\nC:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\REGASM D:\\component\\Terminal.dll /codebase\r\n```\r\n\r\n#### 第二步：修改注册表，解决 ASP 0177 : 8000ffff 错误 ####\r\n\r\n对于32位系统，找到如下注册表位置：\r\n\u003e HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Internet Explorer\\MAIN\\FeatureControl\\FEATURE_IGNORE_ZONES_INITIALIZATION_FAILURE_KB945701\r\n\r\n对于64位系统，找到如下注册表位置：\r\n\u003e HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Internet Explorer\\MAIN\\FeatureControl\\FEATURE_IGNORE_ZONES_INITIALIZATION_FAILURE_KB945701\r\n\r\n选择或者新建项\u003ccode\u003eFEATURE_IGNORE_ZONES_INITIALIZATION_FAILURE_KB945701\u003c/code\u003e，然后新建DWORD值：\r\n\r\n\u003e 名称：w3wp.exe\r\n\u003e 值：1\r\n\r\n#### 第三步：启动Console ####\r\n\r\n双击Console.exe，打开NodeAsp调试命令行。\r\n\r\n#### 第四步：调试 ####\r\n\r\n在default.asp中输入以下代码，然后通过浏览器访问default.asp。接下来，你就可以在`Console.exe`中看到结果了。\r\n\r\n```javascript\r\nvar a = {name: \"nodeasp\", value: true}\r\n// 在console中将输出\r\n//{\r\n//    name: \"nodeasp\",\r\n//    value: true\r\n//}\r\n```\r\n\r\n### 模块方法 ###\r\n\r\n#### console.log() ####\r\n\r\n向Console输出，使用默认颜色。\r\n\r\n```javascript\r\nvar a = {name: \"NodeAsp\", version: \"0.0.1\"};\r\nconsole.log(a);\r\n```\r\n\r\n#### console.info() ####\r\n\r\n向Console输出，使用绿色。\r\n\r\n#### console.error() ####\r\n\r\n向Console输出，使用红色。特别地，如果输出的是Error对象，将显示完整的错误信息。\r\n\r\n#### console.warn() ####\r\n\r\n向Console输出，使用黄色。\r\n\r\n#### console.time(label) ####\r\n\r\n使用label指定名称，开始一个计时器，用于计算操作所需要花费的时间。\r\n\r\n#### console.timeEnd(label) ####\r\n\r\n输出某项操作所需要消耗的时间。\r\n\r\nExample:\r\n\r\n```javascript\r\n    console.time('100-elements');\r\n    for (var i = 0; i \u003c 100; i++) {\r\n      ;\r\n    }\r\n    console.timeEnd('100-elements');\r\n    // prints 100-elements: 262ms\r\n```\r\n\r\n### 命令 ###\r\n\r\n在控制台中可以输入以下命令。\r\n\r\n* cls/clear：清空调试信息，不可恢复。\r\n\r\n* about：显示关于信息。\r\n\r\n* copylast：复制上一条输出信息。\r\n\r\n* copyall：复制所有输出信息。\r\n\r\n## 模块 ##\r\n\r\nNodeAsp有一个跟NodeJS几乎一致的模块加载系统，这样可以保证NodeAsp可以直接使用大量NodeJS的模块。\r\n\r\nNodeAsp的核心几乎不包含任何开发网站需要功能，所有功能都是通过模块来扩展的。可以通过NodeAsp的[模块中心](http://nap.webkits.cn/\")或者[NPM](http://npmjs.org)来寻找您所需要的功能模块。\r\n\r\n在NodeAsp中，文件和模块是一一对应的。下面是示例foo.js加载同一目录下的circle.js。\r\n\r\nfoo.js的内容\r\n\r\n```javascript\r\nvar circle = require('./circle.js');\r\nconsole.log( 'The area of a circle of radius 4 is '\r\n+ circle.area(4));\r\n```\r\n\r\ncircle.js的内容:\r\n\r\n```javascript\r\nvar PI = Math.PI;\r\nexports.area = function (r) {\r\n    return PI * r * r;\r\n};\r\nexports.circumference = function (r) {\r\n    return 2 * PI * r;\r\n};\r\n```\r\n\r\ncircle.js模块输出了area()和circumference()两个函数。要输出某个对象，把它加到exports这个特殊对象下即可。\r\n\r\n注意，exports是module.exports的一个引用，只是为了用起来方便。当你想输出的是例如构造函数这样的单个项目，那么需要使用module.exports。\r\n\r\n```javascript\r\n// 正确输出构造函数\r\nmodule.exports = MyConstructor;\r\n```\r\n\r\n模块内的本地变量是私有的。在这个例子中，PI这个变量就是circle.js私有的。\r\n\r\n### 循环 ###\r\n\r\n考虑这样一种情形:\r\n\r\na.js\r\n\r\n```javascript\r\nconsole.log('a starting');\r\nexports.done = false;\r\nvar b = require('./b.js');\r\nconsole.log('in a, b.done = %j', b.done);\r\nexports.done = true;\r\nconsole.log('a done');\r\n```\r\n\r\nb.js\r\n\r\n```javascript\r\nconsole.log('b starting');\r\nexports.done = false;\r\nvar a = require('./a.js');\r\nconsole.log('in b, a.done = %j', a.done);\r\nexports.done = true;\r\nconsole.log('b done');\r\n```\r\n\r\nmain.js\r\n\r\n```javascript\r\nconsole.log('main starting');\r\nvar a = require('./a.js');\r\nvar b = require('./b.js');\r\nconsole.log('in main, a.done=%j, b.done=%j', a.done, b.done);\r\n```\r\n\r\n首先main.js加载a.js,接着a.js又去加载b.js。这时，b.js会尝试去加载a.js。为了防止无限的循环，a.js会返回一个unfinished copy给b.js。然后b.js就会停止加载，并将其exports对象返回给a.js模块。\r\n\r\n这样main.js就把这两个模块都加载完成了。这段程序的输出如下：\r\n\r\n```javascript\r\nmain starting\r\na starting\r\nb starting\r\nin b, a.done = false\r\nb done\r\nin a, b.done = true\r\na done\r\nin main, a.done=true, b.done=true\r\n```\r\n\r\n跟NodeJS一样，通常循环依赖模块并不会导致死循环，但是如果此时直接在模块加载时执行其它模块的方法，会提示找不到对应的方法，所以应该避开这种情况。\r\n\r\n```javascript\r\n// a.js\r\nvar b = require('./b.js');\r\n    exports.add = function(m, n) {\r\n    console.info(m + n);\r\n};\r\n\r\n// b.js\r\nvar a = require('./a');\r\nvar m = 101, n = 102;\r\nexports.result = function() {\r\n    a.add(m, n);        // 此处没有问题\r\n};\r\na.add(m, n);            // 此处会报错，找不到a.add方法\r\n```\r\n\r\n### 文件模块 ###\r\n\r\n如果按文件名没有查找到，那么NodeAsp会添加` .js`和` .json`后缀名，再尝试加载。\r\n\r\n` .js`会被解析为Javascript纯文本文件，` .json`会被解析为JSON格式的纯文本文件。\r\n\r\n模块以'/'为前缀，则表示绝对路径。例如，require('/home/marco/foo.js') ，加载的是/home/marco/foo.js这个文件。\r\n\r\n模块以'./'为前缀，则路径是相对于调用require()的文件。 也就是说，circle.js必须和foo.js在同一目录下，require('./circle')才能找到。\r\n\r\n当没有以'/'或者'./'来指向一个文件时，这个模块是从node_modules文件夹加载的。\r\n\r\n如果指定的路径不存在，require()会抛出一个错误。\r\n\r\n\u003e NOTE: 考虑到IIS主机上，` .js`文件可以直接通过浏览器访问，所以如果不希望泄露源码，您也可以使用任意文件后缀名。\r\n\r\n### 从node_modules文件夹中加载 ###\r\n\r\n如果require()中的模块名不是一个本地模块，也没有以'/', '../', 或是 './'开头，那么node会从当前模块的父目录开始，尝试在它的/node_modules文件夹里加载相应模块。\r\n\r\n如果没有找到，那么就再向上移动到父目录，直到到达顶层目录位置。\r\n\r\n例如，如果位于'/home/ry/projects/foo.js'的文件调用了require('bar.js')，那么node查找的位置依次为：\r\n\r\n* /home/ry/projects/node_modules/bar.js\r\n\r\n* /home/ry/node_modules/bar.js\r\n\r\n* /home/node_modules/bar.js\r\n\r\n* /node_modules/bar.js\r\n\r\n### 模块包 ###\r\n\r\n可以把程序和库放到一个单独的文件夹里，并提供单一入口来指向它。有三种方法，使一个文件夹可以作为require()的参数来加载。\r\n\r\n首先是在文件夹的根目录创建一个叫做package.json的文件，它需要指定一个main模块。下面是一个package.json文件的示例。\r\n\r\n```javascript\r\n{\r\n    \"name\" : \"some-library\",\r\n    \"main\" : \"./lib/some-library.js\"\r\n}\r\n```\r\n\r\n示例中这个文件，如果是放在./some-library目录下面，那么require('./some-library')就将会去加载./some-library/lib/some-library.js。\r\n\r\n如果目录里没有package.json这个文件，那么node就会尝试去加载这个路径下的index.js。\r\n\r\n### 缓存 ###\r\n\r\n模块在第一次加载后会被缓存。这意味着（类似其他缓存）每次调用require('foo')的时候都会返回同一个对象，当然，必须是每次都解析到同一个文件。\r\n\r\n多次调用 require(foo) 未必会导致模块中的代码执行多次. 这是一个重要的功能. 借助这个功能, 可以返回部分完成的对象; 这样, 传递依赖也能被加载, 即使它们可能导致循环依赖。\r\n\r\n如果你希望一个模块多次执行，那么就输出一个函数，然后调用这个函数。\r\n\r\n模块的缓存是依赖于解析后的文件名。由于随着调用的位置不同，可能解析到不同的文件（比如需从node_modules文件夹加载的情况），所以，如果解析到其他文件时，就不能保证require('foo')总是会返回确切的同一对象。\r\n\r\n### 模块对象 ###\r\n\r\n在每一个模块中，变量 module 是一个代表当前模块的对象的引用。 特别地，module.exports 可以通过全局模块对象 exports 获取到。 module 不是事实上的全局对象，而更像是每个模块内部的。\r\n\r\n#### module.exports ####\r\n\r\nmodule.exports对象是通过模块系统产生的。因此，只需要将要导出的对象赋值给`module.exports`。例如，我们也可以使用下面的方法来写circle.js，这是完全等效的。\r\n\r\n```javascript\r\n// circle.js\r\nvar PI = Math.PI;\r\nvar circle = {};\r\ncircle.area = function (r) {\r\n    return PI * r * r;\r\n};\r\ncircle.circumference = function (r) {\r\n    return 2 * PI * r;\r\n};\r\nmodule.exports = circle;\r\n```\r\n\r\n#### module.id ####\r\n\r\n用于区别模块的标识符。通常是完全解析后的文件名。\r\n\r\n#### module.filename ####\r\n\r\n模块完全解析后的文件名。\r\n\r\n#### module.parent ####\r\n\r\n引入这个模块的模块。\r\n\r\n### 查找流程 ###\r\n\r\n当使用require()引用一个模块时，是按照如下流程根据表达式来查找目标模块的。\r\n\r\n```javascript\r\nrequire(X) from module at path Y\r\n1. If X begins with './' or '/' or '../'\r\na. LOAD_AS_FILE(Y + X)\r\nb. LOAD_AS_DIRECTORY(Y + X)\r\n2. LOAD_NODE_MODULES(X, dirname(Y))\r\n3. THROW \"not found\"\r\n\r\nLOAD_AS_FILE(X)\r\n1. If X is a file, load X as JavaScript text.  STOP\r\n2. If X.js is a file, load X.js as JavaScript text.  STOP\r\n3. If X.json is a file, parse X.json to a JavaScript Object.  STOP\r\n\r\nLOAD_AS_DIRECTORY(X)\r\n1. If X/package.json is a file,\r\na. Parse X/package.json, and look for \"main\" field.\r\nb. let M = X + (json main field)\r\nc. LOAD_AS_FILE(M)\r\n2. If X/index.js is a file, load X/index.js as JavaScript text.  STOP\r\n3. If X/index.json is a file, parse X/index.json to a JavaScript object. STOP\r\n\r\nLOAD_NODE_MODULES(X, START)\r\n1. let DIRS=NODE_MODULES_PATHS(START)\r\n2. for each DIR in DIRS:\r\na. LOAD_AS_FILE(DIR/X)\r\nb. LOAD_AS_DIRECTORY(DIR/X)\r\n\r\nNODE_MODULES_PATHS(START)\r\n1. let PARTS = path split(START)\r\n2. let I = count of PARTS - 1\r\n3. let DIRS = []\r\n4. while I \u003e= 0,\r\na. if PARTS[I] = \"node_modules\" CONTINUE\r\nc. DIR = path join(PARTS[0 .. I] + \"node_modules\")\r\nb. DIRS = DIRS + DIR\r\nc. let I = I - 1\r\n5. return DIRS\r\n```\r\n\r\n## 内置模块 ##\r\n\r\n内置模块与NodeJS一样，也必需先require才能使用。\r\n\r\n### assert ###\r\n\r\n该模块用于编写程序的单元测试用例，通过require('assert')调用。直接移植自NodeJS。\r\n\r\n### events ###\r\n\r\n事件处理模块，直接移植自NodeJS。\r\n\r\n### fs ###\r\n\r\n文件操作模块，兼容绝大部分NodeJS文件操作模块的同步操作API方法。\r\n\r\n### http ###\r\n\r\nHTTP请求与处理模块。移植并修改自NodeJS，绝大部分兼容。\r\n\r\n### path ###\r\n\r\n本模块包含一套用于处理和转换文件路径的工具集。几乎所有的方法只做字符串变换， 不会调用文件系统检查路径是否有效。\r\n\r\n移植并修改自NodeJS，几乎完全兼容。\r\n\r\n### punycode ###\r\n\r\n编码和解码URL，完全兼容NodeJS。\r\n\r\n### auerystring ###\r\n\r\n处理URL查询字符串，完全兼容NodeJS。\r\n\r\n### url ###\r\n\r\n该模块包含用以 URL 解析的实用函数。 使用 require('url') 来调用该模块。\r\n\r\n完全兼容NodeJS。\r\n\r\n### util ###\r\n\r\n辅助方法模块，兼容4.0以下版本的NodeJS。\r\n\r\n## 编译NodeAsp源码 ##\r\n\r\n编译NodeAsp源码需要安装node环境，同时需要全局安装uglifyJS。\r\n\r\n在命令行中执行`node build`即可，编译好的文件位于bundle目录中。\r\n\r\n```\r\nC:\\Disk\\projects\\NodeAsp\u003enode build\r\n-----------------------\r\n# build nodeAsp success\r\n+ build/NodeAsp.min.asp\r\n@ 2016-03-01 13:46:04\r\n-----------------------\r\n```\r\n  \r\n## License ##\r\n\r\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspikef%2Fnodeasp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspikef%2Fnodeasp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspikef%2Fnodeasp/lists"}