如何用用命令行开启nodejs搭建web服务器

JavaScript010

如何用用命令行开启nodejs搭建web服务器,第1张

首先,需要安装nodejs,这个可以去官网下载,目前我本地安装的v0.12版本。

安装完成后可以通过命令行测试安装是否成功,输入:node -v,应该会显示当前安装node版本号。

本文中用到的模块,都是nodejs核心模块,不需要从外部下载,如果有需要,可以使用以下命令安装:npm install xxx。

开始

下一步,新建js文件,可以命名为server.js,代码如下:

var http = require('http')

var url = require('url')

var path = require('path')

var fs = require('fs')

var dir, arg = process.argv[2] || ''// 命令行第三个参数,用来接收目录,可为空,相对当前server.js文件的目录名称

// 比如使用命令 node server debug,意思就是debug文件夹与server.js文件同级

// 且你想以debug文件夹启动web服务

http.createServer(function (req, res) {

var pathname = __dirname + url.parse(req.url).pathname

dir = dir ? dir : pathname// 记住dir(目录)

pathname = dir ? pathname.replace(dir, dir + arg + '/') : pathname// 替换文件静态路径

if (path.extname(pathname) == "") {

pathname += "/"

}

if (pathname.charAt(pathname.length - 1) == "/") {

pathname += "index.html"// 入口文件,此处默认index.html

}

fs.exists(pathname, function (exists) {

if (exists) {

switch (path.extname(pathname)) {

case ".html":

res.writeHead(200, {"Content-Type": "text/html"})

break

case ".js":

res.writeHead(200, {"Content-Type": "text/javascript"})

break

case ".css":

res.writeHead(200, {"Content-Type": "text/css"})

break

case ".gif":

res.writeHead(200, {"Content-Type": "image/gif"})

break

case ".jpg":

res.writeHead(200, {"Content-Type": "image/jpeg"})

break

case ".png":

res.writeHead(200, {"Content-Type": "image/png"})

break

default:

res.writeHead(200, {"Content-Type": "application/octet-stream"})

}

// res可以自己添加信息来简单交互 比如可以修改点header信息 或者修改返回的资源数据

fs.readFile(pathname, function (err, data) {

res.end(data)

})

}

else {

res.writeHead(404, {"Content-Type": "text/html"})

res.end("<h1>404 Not Found</h1>")

}

})

}).listen(8085, "127.0.0.5")// 服务器端口

console.log("server running at http://127.0.0.5:8085/")

启动

当node安装完成及上述server.js文件也新建好之后。将其与你要访问的文件夹放在一起,可以放同层或者直接下层。比如,如果你要访问d:\test\debug文件夹。

你可以先将当前文件放入同层或者直接下,然后输入如下命令启动web服务:

先打开`cmd`,进入server文件所在目录,比如是`test`目录;

然后输入:`node server debug`(同层), 或者`node server`(子层),

此时会提示`server running at http://127.0.0.5:8085/`, 表示启动服务成功;

最后打开浏览器,进入:`127.0.0.5:8085`,即可访问此资源。

微应用、微模块的入口

SystemJS 是一个基于标准的模块加载器。

工作环境:

特点:

qiankun 框架配套开发支持 html 作为入口(entry) 的资源加载器(loader)。

工作环境:

特点:

为了方便 debugger 使用 Systemjs.import API 进行调试

调用 api import

  - systemJSPrototype.import 实例方法

   - preimport - 处理 script 标签

    -对 type 为 systemjs-module、systemjs-importmap 进行处理

getOrCreateLoad ->loader.instantiate(id, firstParentUrl) loader 就是 Systemjs ->systemInstantiate 判断 shouldFetch(js false, css true

getOrCreateLoad 返回 load 对象

systemjs 除了对 js 也支持 css、json、wasm 文件资源,通过 systemJSPrototype.fetch 方法根据资源的类型判断调用 源生 fetch 获取资源包装成 systemjs 模块规范的对象返回

css 文件包装成 CSSStylesheet 对象返回

CSSStylesheet API

import-html-entry 的源码简洁清晰,进入方法中第一眼就能看到返回值对象

相同点:都是运行时加载

不同点:systemjs 可以通过插件加载 amd udm commonjs es6Module,import html entry 只能加载 umd

systemjs 不仅是个模块加载工具更是有一套标准的模块规范,single-spa 依赖 systemjs 规范通过 js entry 实现微应用、微模块的加载。

importEntry 只支持 umd 的 js 文件,qiankun 通过 importHtml 解析 html 模板分析资源 实现 html entry 的方式加载 微应用。

import-html-entry 作为工具更适合,systemjs 是独立的模块规范 webpack rollup 打包工具都支持 systemjs 规范。

原理都是对 script 标签的资源进行 appendChild 再 remove 的方式加载到全局,对 style 标签的资源进行 fetch 获取和解析。

import-html-entry 源码方面设计的很清晰可以参考 HTML Entry 源码分析 也可以通过 debugger 的方式自己了解。

首先在本地机器上安装并设置MongoDB服务。

从Mongo网站上下载MongoDB,解压到本地目录,比如C:>Mongo

在上一个文件夹内创建数据目录。比如:C:\Mongo\Data

如果数据文件存放在其他地方,那么在用mongod.exe命令启动MongoDB时,需要在命令行加参数—-dbpath

启动服务

MongoDB提供了两种方式:mongod.exe以后台进程启动;mongo.exe启动命令行界面,可做管理操作。这两个可执行文件都位于Mongo\bin目录下;

进入Mongo安装目录的bin目录下,比如:C:>cd Mongo\bin

有两种启动方式,如下:

mongod.exe –dbpath C:\Mongo\data

或者

mongod.exe –config mongodb.config

mongodb.config是Mongo\bin目录下的配置文件,需要在此配置文件中指定数据目录(比如,dbpath= C:\Mongo\Data)的位置。

连接到MongoDB,到这一步,mongo后台服务已经启动,可以通过http://localhost:27017查看。 MongoDB启动运行后,我们接下来看它的聚合函数。

实现聚合函数

在关系数据库中,我们可以在数值型字段上执行包含预定义聚合函数的SQL语句,比如,SUM()、COUNT()、MAX()和MIN()。但是在MongoDB中,需要通过MapReduce功能来实现聚合以及批处理,它跟SQL里用来实现聚合的GROUP BY从句比较类似。下一节将描述关系数据库中SQL方式实现的聚合和相应的通过MongoDB提供的MapReduce实现的聚合。

为了讨论这个主题,我们考虑如下所示的Sales表,它以MongoDB中的反范式形式呈现。

Sales表

#

列名

数据类型

1

OrderId

INTEGER

2

OrderDate

STRING

3

Quantity

INTEGER

4

SalesAmt

DOUBLE

5

Profit

DOUBLE

6

CustomerName

STRING

7

City

STRING

8

State

STRING

9

ZipCode

STRING

10

Region

STRING

11

ProductId

INTEGER

12

ProductCategory

STRING

13

ProductSubCategory

STRING

14

ProductName

STRING

15

ShipDate

STRING

基于SQL和MapReduce的实现

我们提供了一个查询的样例集,这些查询使用聚合函数、过滤条件和分组从句,及其等效的MapReduce实现,即MongoDB实现SQL中GROUP BY的等效方式。在MongoDB存储的文档上执行聚合操作非常有用,这种方式的一个限制是聚合函数(比如,SUM、AVG、MIN、MAX)需要通过mapper和reducer函数来定制化实现。

MongoDB没有原生态的用户自定义函数(UDFs)支持。但是它允许使用db.system.js.save命令来创建并保存JavaScript函数,JavaScript函数可以在MapReduce中复用。下表是一些常用的聚合函数的实现。稍后,我们会讨论这些函数在MapReduce任务中的使用。

聚合函数

Javascript 函数

SUM

db.system.js.save( { _id : "Sum" ,

value : function(key,values)

{

var total = 0

for(var i = 0i <values.lengthi++)

total += values[i]

return total

}})

AVERAGE

db.system.js.save( { _id : "Avg" ,

value : function(key,values)

{

var total = Sum(key,values)

var mean = total/values.length

return mean

}})

MAX

db.system.js.save( { _id : "Max" ,

value : function(key,values)

{

var maxValue=values[0]

for(var i=1i

MIN

db.system.js.save( { _id : "Min" ,

value : function(key,values)

{

var minValue=values[0]

for(var i=1i

VARIANCE

db.system.js.save( { _id : "Variance" ,

value : function(key,values)

{

var squared_Diff = 0

var mean = Avg(key,values)

for(var i = 0i <values.lengthi++)

{

var deviation = values[i] - mean

squared_Diff += deviation * deviation

}

var variance = squared_Diff/(values.length)

return variance

}})

STD DEVIATION

db.system.js.save( { _id : "Standard_Deviation"

, value : function(key,values)

{

var variance = Variance(key,values)

return Math.sqrt(variance)

}})

SQL和MapReduce脚本在四种不同的用例场景中实现聚合函数的代码片段如下表所示。

1.各地区的平均订单量

下面的查询是用来获取不同地区的平均订单量。

SQL Query

MapReduce Functions

SELECT

db.sales.runCommand(

{

mapreduce : "sales" ,

City,

State,

Region,

map:function()

{ // emit function handles the group by

emit( {

// Key

city:this.City,

state:this.State,

region:this.Region},

// Values

this.Quantity)

},

AVG(Quantity)

reduce:function(key,values)

{

var result = Avg(key, values)

return result

}

FROM sales

GROUP BY City, State, Region

// Group By is handled by the emit(keys, values)

line in the map() function above

out : { inline : 1 } })

2.产品的分类销售总额

下面的查询是用来获取产品的分类销售额,根据产品类别的层级分组。在下面例子中,不同的产品类别作为个体维度,它们也可以被称为更复杂的基于层次的维度。

SQL 查询

MapReduce 函数

SELECT

db.sales.runCommand(

{

mapreduce : "sales" ,

ProductCategory, ProductSubCategory, ProductName,

map:function()

{

emit(

// Key

{key0:this.ProductCategory,

key1:this.ProductSubCategory,

key2:this.ProductName},

// Values

this.SalesAmt)

},

SUM(SalesAmt)

reduce:function(key,values)

{

var result = Sum(key, values)

return result

}

FROM sales

GROUP BY ProductCategory, ProductSubCategory, ProductName

// Group By is handled by the emit(keys, values)

line in the map() function above

out : { inline : 1 } })

3. 一种产品的最大利润

下面的查询是用来获取一个给定产品基于过滤条件的最大利润。

SQL查询

MapReduce 函数

SELECT

db.sales.runCommand(

{

mapreduce : "sales" ,

ProductId, ProductName,

map:function()

{

if(this.ProductId==1)

emit( {

key0:this.ProductId,

key1:this.ProductName},

this.Profit)

},

MAX(SalesAmt)

reduce:function(key,values)

{

var maxValue=Max(key,values)

return maxValue

}

FROM sales

WHERE ProductId=’1’

// WHERE condition implementation is provided in

map() function

GROUP BY ProductId, ProductName

// Group By is handled by the emit(keys, values)

line in the map() function above

out : { inline : 1 } })

4. 总量、总销售额、平均利润

这个场景的需求是计算订单的总数、总销售额和平均利润,订单ID在1到10之间,发货时间在2011年的1月1日到12月31日之间。下面的查询是用来执行多个聚合,比如,在指定年份以及指定的不同区域和产品类别范围里订单的总数、总销售额和平均利润。

SQL 查询

MapReduce 函数

SELECT

db.sales.runCommand(

{ mapreduce : "sales" ,

Region,

ProductCategory,

ProductId,

map:function()

{

emit( {

// Keys

region:this.Region,

productCategory:this.ProductCategory,

productid:this.ProductId},

// Values

{quantSum:this.Quantity,

salesSum:this.SalesAmt,

avgProfit:this.Profit} )

}

Sum(Quantity),

Sum(Sales),

Avg(Profit)

reduce:function(key,values)

{

var result=

{quantSum:0,salesSum:0,avgProfit:0}

var count = 0

values.forEach(function(value)

{

// Calculation of Sum(Quantity)

result.quantSum += values[i].quantSum

// Calculation of Sum(Sales)

result.salesSum += values[i].salesSum

result.avgProfit += values[i].avgProfit

count++

}

// Calculation of Avg(Profit)

result.avgProfit = result.avgProfit / count

return result

},

FROM Sales

WHERE

Orderid between 1 and 10 AND

Shipdate BETWEEN ‘01/01/2011’ and

‘12/31/2011’

query : {

"OrderId" : { "$gt" : 1 },

"OrderId" : { "$lt" : 10 },

"ShipDate" : { "$gt" : "01/01/2011" },

"ShipDate" : { "$lt" : "31/12/2011" },

},

GROUP BY

Region, ProductCategory, ProductId

// Group By is handled by the emit(keys, values)

line in the map() function above

LIMIT 3

limit : 3,

out : { inline : 1 } })

既然我们已经看了在不同业务场景下的聚合函数的代码示例,接下来我们准备来测试这些函数。

测试聚合函数

MongoDB的MapReduce功能通过数据库命令来调用。Map和Reduce函数在前面章节里已经使用JavaScript实现。下面是执行MapReduce函数的语法。

db.runCommand(

{ mapreduce : <collection>,

map : <mapfunction>,

reduce : <reducefunction>

[, query : <query filter object>]

[, sort : <sorts the input objects using this key. Useful for

optimization, like sorting by the emit key for fewer reduces>]

[, limit : <number of objects to return from collection>]

[, out : <see output options below>]

[, keeptemp: <true|false>]

[, finalize : <finalizefunction>]

[, scope : <object where fields go into javascript global scope >]

[, jsMode : true]

[, verbose : true]

}

)

Where the Output Options include:

{ replace : "collectionName" }

{ merge : "collectionName"

{ reduce : "collectionName" }

{ inline : 1}