写一个 nodejs npm应用 - webhere
前言、没图不说话,先上图。

What's webhere?
有没有遇到这样的场景:写程序的时候,需要访问一个文件,这个文件 需要是放到一台web服务器上,但是你不是开发的web应用。
所以呢,你不得不去找一个web服务器,把你的文件上传上去,或者干脆直接创建一个web应用程序...
webhere就是来解决这个问题,在你想要当做web根目录的目录下,打开你亲爱的命令行,敲下webhere,回车,搞定。
然后就可以通过web浏览器访问目录下的文件了。
安装:$ npm install webhere -g
运行:$ webhere
一、 原理
原理比较简单,一句话来说,就是搭建一个web服务器。
1.用nodejs的http包创建一个web服务。
2.对访问路径路由到具体的文件路径。
3.根据文件是否存在写具体的响应码,根据文件的后缀写具体Content-type。
4.返回文件的内容,响应结束。
二、 实现
1.创建nodejs的pakage.json,添加应用的bin的信息和其他描述信息。
{
"name": "webhere",
"version": "0.0.7",
"description": "Create a web server in the current directory.",
"repository": {
"type": "git",
"url": "git@github.com:smallyard/webhere.git"
},
"author": "liuhongqiang <liuhongqiang@live.cn>",
"license": "MIT",
"bin": {
"webhere": "./bin/webhere"
},
"keywords": [
"webhere",
"server",
"web server"
],
"engines": {
"node": ">= 0.10"
},
"readmeFilename": "README.md"
}
2.bin文件,程序的入口。
#!/usr/bin/env node
var server = require("../src/server");
server.start();
3.web服务,server.js
var http = require("http");
var router = require("./router");
var render = require("./render");
function start() {
function onRequest(request, response) {
var routeResult = router.route(request.url);
var responseInfo = render.getResponseInfo(routeResult);
response.writeHead(responseInfo.status, {"Content-Type": responseInfo.contentType});
response.write(responseInfo.content);
response.end();
}
http.createServer(onRequest).listen(9000);
console.log("Server has started.");
console.log("Server address: http://127.0.0.1:9000");
}
exports.start = start;
4.路由router.js
var fs = require("fs");
function route(path) {
console.log("Origin path: " + path);
if (path == "/") {
return "htmlIndex";
} else {
path = "." + path;
if (fs.existsSync(path) && fs.statSync(path).isFile()) {
return path;
} else {
return "html404";
}
}
}
exports.route = route;
5.内容渲染,render.js
var fs = require("fs");
var contentTypes = require("./contentTypes");
var HTML_INDEX = require("./html/index").html;
var HTML_404 = require("./html/404").html;
function getResponseInfo(routeResult) {
console.log("Result path: " + routeResult);
var status = 200;
var content = "";
var contentType = "text/html";
if (routeResult == "htmlIndex") {
content = HTML_INDEX;
} else if (routeResult == "html404") {
status = 404;
content = HTML_404;
} else {
content = fs.readFileSync(routeResult);
contentType = getContentType(routeResult);
}
return {
"status": status,
"contentType": contentType,
"content": content
};
}
function getContentType(filePath) {
var suffix = "";
var pointIndex = filePath.lastIndexOf(".");
if (pointIndex != -1) {
suffix = filePath.substr(pointIndex);
}
if (contentTypes.hasOwnProperty(suffix)) {
return contentTypes[suffix];
} else {
return contentTypes[".*"];
}
}
exports.getResponseInfo = getResponseInfo;
最后,附上我从开源中国上抓取的content-type
{
".*": "application/octet-stream",
".tif": "application/x-tif",
".001": "application/x-001",
".301": "application/x-301",
".323": "text/h323",
".906": "application/x-906",
".907": "drawing/907",
".a11": "application/x-a11",
".acp": "audio/x-mei-aac",
".ai": "application/postscript",
".aif": "audio/aiff",
".aifc": "audio/aiff",
".aiff": "audio/aiff",
".anv": "application/x-anv",
".asa": "text/asa",
".asf": "video/x-ms-asf",
".asp": "text/asp",
".asx": "video/x-ms-asf",
".au": "audio/basic",
".avi": "video/avi",
".awf": "application/vnd.adobe.workflow",
".biz": "text/xml",
".bmp": "application/x-bmp",
".bot": "application/x-bot",
".c4t": "application/x-c4t",
".c90": "application/x-c90",
".cal": "application/x-cals",
".cat": "application/vnd.ms-pki.seccat",
".cdf": "application/x-netcdf",
".cdr": "application/x-cdr",
".cel": "application/x-cel",
".cer": "application/x-x509-ca-cert",
".cg4": "application/x-g4",
".cgm": "application/x-cgm",
".cit": "application/x-cit",
".class": "java/*",
".cml": "text/xml",
".cmp": "application/x-cmp",
".cmx": "application/x-cmx",
".cot": "application/x-cot",
".crl": "application/pkix-crl",
".crt": "application/x-x509-ca-cert",
".csi": "application/x-csi",
".css": "text/css",
".cut": "application/x-cut",
".dbf": "application/x-dbf",
".dbm": "application/x-dbm",
".dbx": "application/x-dbx",
".dcd": "text/xml",
".dcx": "application/x-dcx",
".der": "application/x-x509-ca-cert",
".dgn": "application/x-dgn",
".dib": "application/x-dib",
".dll": "application/x-msdownload",
".doc": "application/msword",
".dot": "application/msword",
".drw": "application/x-drw",
".dtd": "text/xml",
".dwf": "application/x-dwf",
".dwg": "application/x-dwg",
".dxb": "application/x-dxb",
".dxf": "application/x-dxf",
".edn": "application/vnd.adobe.edn",
".emf": "application/x-emf",
".eml": "message/rfc822",
".ent": "text/xml",
".epi": "application/x-epi",
".eps": "application/postscript",
".etd": "application/x-ebx",
".exe": "application/x-msdownload",
".fax": "image/fax",
".fdf": "application/vnd.fdf",
".fif": "application/fractals",
".fo": "text/xml",
".frm": "application/x-frm",
".g4": "application/x-g4",
".gbr": "application/x-gbr",
".": "application/x-",
".gif": "image/gif",
".gl2": "application/x-gl2",
".gp4": "application/x-gp4",
".hgl": "application/x-hgl",
".hmr": "application/x-hmr",
".hpg": "application/x-hpgl",
".hpl": "application/x-hpl",
".hqx": "application/mac-binhex40",
".hrf": "application/x-hrf",
".hta": "application/hta",
".htc": "text/x-component",
".htm": "text/html",
".html": "text/html",
".htt": "text/webviewhtml",
".htx": "text/html",
".icb": "application/x-icb",
".ico": "application/x-ico",
".iff": "application/x-iff",
".ig4": "application/x-g4",
".igs": "application/x-igs",
".iii": "application/x-iphone",
".img": "application/x-img",
".ins": "application/x-internet-signup",
".isp": "application/x-internet-signup",
".IVF": "video/x-ivf",
".java": "java/*",
".jfif": "image/jpeg",
".jpe": "application/x-jpe",
".jpeg": "image/jpeg",
".jpg": "application/x-jpg",
".js": "application/x-javascript",
".jsp": "text/html",
".la1": "audio/x-liquid-file",
".lar": "application/x-laplayer-reg",
".latex": "application/x-latex",
".lavs": "audio/x-liquid-secure",
".lbm": "application/x-lbm",
".lmsff": "audio/x-la-lms",
".ls": "application/x-javascript",
".ltr": "application/x-ltr",
".m1v": "video/x-mpeg",
".m2v": "video/x-mpeg",
".m3u": "audio/mpegurl",
".m4e": "video/mpeg4",
".mac": "application/x-mac",
".man": "application/x-troff-man",
".math": "text/xml",
".mdb": "application/x-mdb",
".mfp": "application/x-shockwave-flash",
".mht": "message/rfc822",
".mhtml": "message/rfc822",
".mi": "application/x-mi",
".mid": "audio/mid",
".midi": "audio/mid",
".mil": "application/x-mil",
".mml": "text/xml",
".mnd": "audio/x-musicnet-download",
".mns": "audio/x-musicnet-stream",
".mocha": "application/x-javascript",
".movie": "video/x-sgi-movie",
".mp1": "audio/mp1",
".mp2": "audio/mp2",
".mp2v": "video/mpeg",
".mp3": "audio/mp3",
".mp4": "video/mpeg4",
".mpa": "video/x-mpg",
".mpd": "application/vnd.ms-project",
".mpe": "video/x-mpeg",
".mpeg": "video/mpg",
".mpg": "video/mpg",
".mpga": "audio/rn-mpeg",
".mpp": "application/vnd.ms-project",
".mps": "video/x-mpeg",
".mpt": "application/vnd.ms-project",
".mpv": "video/mpg",
".mpv2": "video/mpeg",
".mpw": "application/vnd.ms-project",
".mpx": "application/vnd.ms-project",
".mtx": "text/xml",
".mxp": "application/x-mmxp",
".net": "image/pnetvue",
".nrf": "application/x-nrf",
".nws": "message/rfc822",
".odc": "text/x-ms-odc",
".out": "application/x-out",
".p10": "application/pkcs10",
".p12": "application/x-pkcs12",
".p7b": "application/x-pkcs7-certificates",
".p7c": "application/pkcs7-mime",
".p7m": "application/pkcs7-mime",
".p7r": "application/x-pkcs7-certreqresp",
".p7s": "application/pkcs7-signature",
".pc5": "application/x-pc5",
".pci": "application/x-pci",
".pcl": "application/x-pcl",
".pcx": "application/x-pcx",
".pdf": "application/pdf",
".pdx": "application/vnd.adobe.pdx",
".pfx": "application/x-pkcs12",
".pgl": "application/x-pgl",
".pic": "application/x-pic",
".pko": "application/vnd.ms-pki.pko",
".pl": "application/x-perl",
".plg": "text/html",
".pls": "audio/scpls",
".plt": "application/x-plt",
".png": "application/x-png",
".pot": "application/vnd.ms-powerpoint",
".ppa": "application/vnd.ms-powerpoint",
".ppm": "application/x-ppm",
".pps": "application/vnd.ms-powerpoint",
".ppt": "application/x-ppt",
".pr": "application/x-pr",
".prf": "application/pics-rules",
".prn": "application/x-prn",
".prt": "application/x-prt",
".ps": "application/postscript",
".ptn": "application/x-ptn",
".pwz": "application/vnd.ms-powerpoint",
".r3t": "text/vnd.rn-realtext3d",
".ra": "audio/vnd.rn-realaudio",
".ram": "audio/x-pn-realaudio",
".ras": "application/x-ras",
".rat": "application/rat-file",
".rdf": "text/xml",
".rec": "application/vnd.rn-recording",
".red": "application/x-red",
".rgb": "application/x-rgb",
".rjs": "application/vnd.rn-realsystem-rjs",
".rjt": "application/vnd.rn-realsystem-rjt",
".rlc": "application/x-rlc",
".rle": "application/x-rle",
".rm": "application/vnd.rn-realmedia",
".rmf": "application/vnd.adobe.rmf",
".rmi": "audio/mid",
".rmj": "application/vnd.rn-realsystem-rmj",
".rmm": "audio/x-pn-realaudio",
".rmp": "application/vnd.rn-rn_music_package",
".rms": "application/vnd.rn-realmedia-secure",
".rmvb": "application/vnd.rn-realmedia-vbr",
".rmx": "application/vnd.rn-realsystem-rmx",
".rnx": "application/vnd.rn-realplayer",
".rp": "image/vnd.rn-realpix",
".rpm": "audio/x-pn-realaudio-plugin",
".rsml": "application/vnd.rn-rsml",
".rt": "text/vnd.rn-realtext",
".rtf": "application/x-rtf",
".rv": "video/vnd.rn-realvideo",
".sam": "application/x-sam",
".sat": "application/x-sat",
".sdp": "application/sdp",
".sdw": "application/x-sdw",
".sit": "application/x-stuffit",
".slb": "application/x-slb",
".sld": "application/x-sld",
".slk": "drawing/x-slk",
".smi": "application/smil",
".smil": "application/smil",
".smk": "application/x-smk",
".snd": "audio/basic",
".sol": "text/plain",
".sor": "text/plain",
".spc": "application/x-pkcs7-certificates",
".spl": "application/futuresplash",
".spp": "text/xml",
".ssm": "application/streamingmedia",
".sst": "application/vnd.ms-pki.certstore",
".stl": "application/vnd.ms-pki.stl",
".stm": "text/html",
".sty": "application/x-sty",
".svg": "text/xml",
".swf": "application/x-shockwave-flash",
".tdf": "application/x-tdf",
".tg4": "application/x-tg4",
".tga": "application/x-tga",
".tiff": "image/tiff",
".tld": "text/xml",
".top": "drawing/x-top",
".torrent": "application/x-bittorrent",
".tsd": "text/xml",
".txt": "text/plain",
".uin": "application/x-icq",
".uls": "text/iuls",
".vcf": "text/x-vcard",
".vda": "application/x-vda",
".vdx": "application/vnd.visio",
".vml": "text/xml",
".vpg": "application/x-vpeg005",
".vsd": "application/x-vsd",
".vss": "application/vnd.visio",
".vst": "application/x-vst",
".vsw": "application/vnd.visio",
".vsx": "application/vnd.visio",
".vtx": "application/vnd.visio",
".vxml": "text/xml",
".wav": "audio/wav",
".wax": "audio/x-ms-wax",
".wb1": "application/x-wb1",
".wb2": "application/x-wb2",
".wb3": "application/x-wb3",
".wbmp": "image/vnd.wap.wbmp",
".wiz": "application/msword",
".wk3": "application/x-wk3",
".wk4": "application/x-wk4",
".wkq": "application/x-wkq",
".wks": "application/x-wks",
".wm": "video/x-ms-wm",
".wma": "audio/x-ms-wma",
".wmd": "application/x-ms-wmd",
".wmf": "application/x-wmf",
".wml": "text/vnd.wap.wml",
".wmv": "video/x-ms-wmv",
".wmx": "video/x-ms-wmx",
".wmz": "application/x-ms-wmz",
".wp6": "application/x-wp6",
".wpd": "application/x-wpd",
".wpg": "application/x-wpg",
".wpl": "application/vnd.ms-wpl",
".wq1": "application/x-wq1",
".wr1": "application/x-wr1",
".wri": "application/x-wri",
".wrk": "application/x-wrk",
".ws": "application/x-ws",
".ws2": "application/x-ws",
".wsc": "text/scriptlet",
".wsdl": "text/xml",
".wvx": "video/x-ms-wvx",
".xdp": "application/vnd.adobe.xdp",
".xdr": "text/xml",
".xfd": "application/vnd.adobe.xfd",
".xfdf": "application/vnd.adobe.xfdf",
".xhtml": "text/html",
".xls": "application/x-xls",
".xlw": "application/x-xlw",
".xml": "text/xml",
".xpl": "audio/scpls",
".xq": "text/xml",
".xql": "text/xml",
".xquery": "text/xml",
".xsd": "text/xml",
".xsl": "text/xml",
".xslt": "text/xml",
".xwd": "application/x-xwd",
".x_b": "application/x-x_b",
".sis": "application/vnd.symbian.install",
".sisx": "application/vnd.symbian.install",
".x_t": "application/x-x_t",
".ipa": "application/vnd.iphone",
".apk": "application/vnd.android.package-archive",
".xap": "application/x-silverlight-app"
}
三、 总结
写一个 nodejs npm应用 - webhere的更多相关文章
- linux下面配置安装nodejs+npm
linux下 多亏这一篇文章= =我就卡死在文章所说的这个点里 附大牛链接:http://blog.sitearth.com/nodejs%E4%B8%8A%E4%BD%BF%E7%94%A8mong ...
- 怎么样写一个能告诉你npm包名字是否被占用的工具
事情是这样的: 因为我经常会写一些npm包,但是有时候我写完一个包,npm publish 的时候却被提示说包名字被占用了,要不就改名字,要不就加scope,很无奈.npm 命令行可以通过 npm v ...
- 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具
用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具 前言 上周,同事抱怨说 react 怎么不能像 angular 那样,使用命令行工具来生成一个组件.对呀,平时工作时,想要创建 ...
- 通过npm写一个cli命令行工具
前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要 ...
- 从零开始写一个npm包及上传
最近刚好自己需要写公有npm包及上传,虽然百度上资料都能找到,但是都是比较零零碎碎的,个人就来整理下,如何从零开始写一个npm包及上传. 该篇文件只记录一个大概的流程,一些细节没有记录. tips: ...
- 我想写一个前端开发工具(一):在npm发布模块
有必要说说我为什么要开始写这个,正文从下面的第一条开始 我最近忙于公司的项目,一直没有抽出时间来写文章.本来想每个月写一片文章,保质保量,无奈上个月没有坚持. 这段时间有点忙,主要是由于公司业务调整, ...
- 从零开始写一个npm包,一键生成react组件(偷懒==提高效率)
前言 最近写项目开发新模块的时候,每次写新模块的时候需要创建一个组件的时候(包含组件css,index.js,组件js),就只能会拷贝其他组件修改名称 ,但是写了1-2个后发现效率太低了,而且极容易出 ...
- 80行代码教你写一个Webpack插件并发布到npm
1. 前言 最近在学习 Webpack 相关的原理,以前只知道 Webpack 的配置方法,但并不知道其内部流程,经过一轮的学习,感觉获益良多,为了巩固学习的内容,我决定尝试自己动手写一个插件. 这个 ...
- [NodeJS]使用Node.js写一个简单的在线聊天室
声明:教程来自<Node即学即用>.源代码案例均出自此书.博文仅为个人学习笔记. 第一步:创建一个聊天server. 首先,我们先来写一个Server: var net = require ...
随机推荐
- Java并发之ScheduledExecutorService(schedule、scheduleAtFixedRate、scheduleWithFixedDelay)
package com.thread.test.thread; import java.util.Timer; import java.util.TimerTask; import java.util ...
- CentOS7网络配置
*关于查看IP信息 window中是 ipconfig Linux一般都是 ifconfig 不过CentOS7中 这个命令发生了更改 :ip addr 设置网络 再新建虚拟机向导过程中,有一步[网 ...
- 手写一个json格式化 api
最近写的一个东西需要对json字符串进行格式化然后显示在网页上面. 我就想去网上找找有没有这样的api可以直接调用.百度 json api ,搜索结果都是那种只能在网页上进行校验的工具,没有api. ...
- iNeedle产品介绍
一.产品简介 1.产品背景 1.您曾经遇到过下面的问题和烦恼吗?2.当网站上线以后,如何实时的了解网站的运行状况?3.当网站访问速度慢,是升级服务器?还是升级带宽?还是优化网站代码?4.当网站新上线一 ...
- android canvas d
(以下转自:http://blog.csdn.net/longyi_java/article/details/6930480) 1.基本的绘制图片方法 //Bitmap:图片对象,left:偏移左边的 ...
- 时间同步出现ntpdate[1788]: the NTP socket is in use, exiting
问题: [root@service ~]# ntpdate ntp.api.bz 17 Jun 19:22:23 ntpdate[2701]: the NTP socket is in use, ex ...
- python可分组字典
# -*- encoding: UTF-8 -*- from collections import defaultdict class News(object): def __init__(self, ...
- [麦先生]Laravel框架实现发送短信验证
今天在做到用户注册和个人中心的安全管理时,我借助实现第三方短信平台在Laravel框架中进行手机验证的设置; 由于我们做的是一个为客户提供医疗咨询和保健品网站,所以对客户个人隐私的保护显得尤为重要, ...
- ListView的基础应用
在写完基础的布局之后,下一课我们会学习一下如何使用Android中一个非常重要,但是对于新手略有困难的ListView,甚至很久以前都有人说过,会不会写ListView是Android能否入门的第一步 ...
- DPM检测模型 训练自己的数据集 读取接口修改
(转载请注明作者和出处 楼燚(yì)航的blog :http://www.cnblogs.com/louyihang-loves-baiyan/ 未经允许请勿用于商业用途) 本文主要是针对上一篇基于D ...