nodejs(1)-markdown和服務(wù)器

## 前端開(kāi)發(fā)的工具

### 編輯器:

1. 輕量級(jí)的,依靠插件:sublime;atom(github);vs code(miscrosaft)

2. 集成的:DW;webstorm;hbuild;

---### markdown

markdown是一個(gè)標(biāo)記語(yǔ)言,可以利用一些簡(jiǎn)單的語(yǔ)法來(lái)對(duì)內(nèi)容進(jìn)行排版,可以將markdown文件編譯成html,pdf,一般使用markdown寫筆記、文檔...

eq:一般的項(xiàng)目中都會(huì)README.md文件來(lái)做項(xiàng)目標(biāo)識(shí)。

一般的編輯器都可以編寫markdown,語(yǔ)法簡(jiǎn)單,也有專門的markdown編輯器

#### 使用gulp搭建markdown編譯環(huán)境

1. 執(zhí)行npm init 進(jìn)行項(xiàng)目初始化得到package.json

2. 全局安裝gulp :npm install gulp --global;

3. 在項(xiàng)目中安裝gulp依賴:npm install gulp --save-dev;

4. 創(chuàng)建gulpfile.js文件設(shè)置任務(wù):

注意:npm服務(wù)器在國(guó)外,網(wǎng)絡(luò)影響大,甚至還會(huì)遇到需要翻墻才能下載插件的情況,因此推薦安裝cnpm,cnpm跟npm用法完全一致,只是在執(zhí)行命令時(shí)將npm改為cnpm;【淘寶npm鏡像,這是一個(gè)完整 npmjs.org 鏡像,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證盡量與官方服務(wù)同步】, 鏡像地址:http://npm.taobao.org

執(zhí)行 npm install cnpm -g --registry=https://registry.npm.taobao.org

執(zhí)行cnpm -v? 顯示版本號(hào)即安裝成功

var gulp = require("gulp")

var markdown = require('gulp-markdown');

var mdpdf = require('gulp-markdown-pdf');

gulp.task("compileMDToHtml",function () {

gulp.src("./md/*.md")

.pipe(markdown())

.pipe(gulp.dest("./html"))

})

gulp.task("compileMDToPdf",function () {

gulp.src("./md/*.md")

.pipe(mdpdf())

.pipe(gulp.dest("./pdf"))

})

gulp.task("watch:md",function(){

gulp.watch("./md/*.md",['compileMDToHtml','compileMDToPdf'])

})

gulp.task("default",['compileMDToHtml','compileMDToPdf','watch:md'])

5. 在命令行工具通過(guò)執(zhí)行g(shù)ulp指令來(lái)運(yùn)行g(shù)ulp中的默認(rèn)任務(wù)

#### markdown的簡(jiǎn)單語(yǔ)法

[入門連接,來(lái)自簡(jiǎn)書](http://www.lxweimin.com/p/1e402922ee32/)

---## NodeJS

> 一個(gè)后端技術(shù),研究web應(yīng)用的開(kāi)發(fā)模式...,希望能有能力開(kāi)發(fā)一些簡(jiǎn)單的web服務(wù)器,學(xué)會(huì)操作數(shù)據(jù)庫(kù)等等。

##### 什么是nodeJs

下面是對(duì)官網(wǎng)描述的解析:

Node.js 是一個(gè)基于 Chrome V8 引擎的 JavaScript 運(yùn)行環(huán)境。

> 在Node里面寫JS代碼,很開(kāi)心~~,為什么基于引擎:在web前端中,js運(yùn)行在瀏覽器中,js只是一個(gè)腳本語(yǔ)言,js文件也只是一個(gè)普通的文本文件,只有在瀏覽器中才能發(fā)揮應(yīng)有的作用。瀏覽器內(nèi)部有一個(gè)東西叫做內(nèi)核,瀏覽器內(nèi)核的類型:

> IE :trident/microsoft/ms;chrome:blink(webkit)/google/webkit;firefox:gecko/mozillar/moz;opera:blink(presto)/opera/o; safari:webkit/apple/webkit

> 內(nèi)核里有兩個(gè)東西:渲染引擎(渲染DOM結(jié)構(gòu),CSS)、腳本引擎(編譯執(zhí)行JS代碼)Node.js 使用了一個(gè)事件驅(qū)動(dòng)、非阻塞式 I/O 的模型,使其++輕量++又++高效++。

>NodeJS的優(yōu)點(diǎn):輕量、高效node是使用C++編寫的基于V8引擎的JS運(yùn)行環(huán)境,同時(shí)提供了很多基于ECMAScript的擴(kuò)展對(duì)象。

> node的底層語(yǔ)言是C++,JS是netscope公司創(chuàng)造出來(lái)的,誕生的目的是:在前端做表單驗(yàn)證;netscope將js交給ECMA國(guó)際標(biāo)準(zhǔn)組織->ECMAScript 1.0;

> ECMAScript是JS的語(yǔ)法規(guī)范;所以說(shuō):NODEjs里的js語(yǔ)法和瀏覽器的語(yǔ)法是一樣的。且多出了很多對(duì)象;Node.js 的包管理器 npm,成為世界上最大的開(kāi)放源代碼的生態(tài)系統(tǒng)。

> npm是Node的一個(gè)小兄弟,會(huì)在安裝Node的時(shí)候一起安裝,node package manager;[npmjs](www.npmjs.com)這個(gè)網(wǎng)站上有很多很多的node的工具包來(lái)使用,免費(fèi)的包就有470000+,一般需求的包都可以在這里找到

---##### NodeJS可以干什么?

Node.js 可以解析JS代碼(沒(méi)有瀏覽器安全級(jí)別的限制)提供很多系統(tǒng)級(jí)別的API,如:

> 瀏覽器運(yùn)行JS的時(shí)候,例如AJAX,因?yàn)闉g覽器有同源策略,所以會(huì)出現(xiàn)跨域問(wèn)題,這就是瀏覽器安全限制

> 瀏覽器端js不能操作文件系統(tǒng),但是在NodeJs里就可以* 文件的讀寫* 進(jìn)程的管理* 網(wǎng)絡(luò)通信* ...nodejs可以編寫?yīng)毩⒌姆?wù)端應(yīng)用,也可以向客戶端提供Web內(nèi)容,無(wú)需借助與任何Web服務(wù)器(apache)可以去連接文件系統(tǒng),還能操作數(shù)據(jù)庫(kù)。

> 證明Node完全可以作為后端服務(wù)器的開(kāi)發(fā)工具

> 一般的應(yīng)用分為兩種架構(gòu):B/S(browser/server);C/S(client/server)

> 服務(wù)器的外觀上的話是千奇百怪的,內(nèi)部分為邏輯層(JS-NODE,PHP-APACHE,JAVA-VM)、資源層(文件系統(tǒng),數(shù)據(jù)庫(kù))

是Node選擇了JS,還是JS選擇了Node?

是Node選擇了JS,因?yàn)镴S的受眾較廣,且JS的特性和Node的理念較為符合.

.---##### 為什么要學(xué)習(xí)

nodeJs對(duì)于咱們來(lái)說(shuō),一種語(yǔ)言通吃前后端,并且可以增加咱們的競(jìng)爭(zhēng)力且Node現(xiàn)在較火,它有如下的特點(diǎn):

==nodejs適合高并發(fā)、I/O密集型,可伸縮的網(wǎng)路應(yīng)用,數(shù)據(jù)寫入讀取的應(yīng)用比較好

==> I/O輸入輸出頻繁的應(yīng)用就是I/O密集型==nodejs不適合CPU密集型的應(yīng)用,各種計(jì)算的就不太適合==> CPU密集型應(yīng)用,一般計(jì)算量特別的大!

==nodej間服務(wù)器:==s適合開(kāi)發(fā)中

> 將高并發(fā)的,I/O密集操作交由Node服務(wù)器來(lái)處理,Node服務(wù)器再向真正的Web服務(wù)器發(fā)送請(qǐng)求得到響應(yīng)后返回給前端

---##### nodeJs 學(xué)習(xí)網(wǎng)站

1. [nodejs官網(wǎng)](https://nodejs.org/)我們可以在這里下載node,查看api,版本更新日志等動(dòng)態(tài)

2. [npm官網(wǎng)](https://www.npmjs.com/)我們可以在這這里查找很多很多的node模塊去學(xué)習(xí)

3. [github官網(wǎng)](https://github.com/)

4. [stackoverflow](http://stackoverflow.com/)

5. [掘金](https://juejin.im/);[sgmentFault](https://segmentfault.com)

6. [極客學(xué)院node文檔](http://wiki.jikexueyuan.com/project/nodejs/)

---##### nodeJs安裝

nodeJs版本:

LTS指的是long time support 也就是長(zhǎng)期支持版本,推薦大家安裝Current是現(xiàn)在最新的版本。

請(qǐng)安裝到C盤吧,它占用的內(nèi)存不是很大,不會(huì)卡,否則需要配置全局變量才可以在任意一個(gè)盤下使用。---

##### 搭建第一個(gè)node服務(wù)器

我們?cè)陧?xiàng)目目錄下建立一個(gè)server.js文件:

```

const http = require("http")

const port = 3000

const hostname = '127.0.0.1'

const server = http.createServer((req,res)=>{

res.end('hai hai is handsome')

}).listen(port,()=>{

console.log('server is listening')

})

```

這樣的話只要運(yùn)行后,客戶端訪問(wèn)這個(gè)服務(wù)器的時(shí)候就可以接收到響應(yīng)的信息

在控制臺(tái)里輸入node 文件名+回車(腳本模式),這時(shí),我們的服務(wù)就啟動(dòng)了

這只是一個(gè)簡(jiǎn)單的例子,里面的代碼我們后面都會(huì)詳細(xì)再介紹--

-##### NodeJS運(yùn)行JS代碼的方式

1. 腳:在命令行里執(zhí)行 node 文件名(不需要加后綴名) + enter就可以運(yùn)行腳本文件中的js代碼了。

>如果是js文件的話,不需要加后綴名,如果是其他后綴名的話必須得加

2. REPL模式:在命令行中輸入node后回車,大家會(huì)發(fā)現(xiàn)這個(gè)時(shí)候我們的控制臺(tái)就像chrome瀏覽器里一樣可以運(yùn)行js代碼了,其實(shí)這里就是node離的V8引擎解析js代碼的情況。模式是讀一句返回一句。

注意,在Node里運(yùn)行alert會(huì)報(bào)錯(cuò):alert is not define,原因是:alert是屬于window對(duì)象的一個(gè)方法,window屬于BOM對(duì)象,BOM、DOM屬于宿主對(duì)象,在web前端JS中,瀏覽器就是JS的宿主,所以BOM/DOM是JS在瀏覽器中的宿主對(duì)象,在Node中,Node就是JS的宿主,Node的宿主對(duì)象可沒(méi)有BOM/DOM,更沒(méi)有window了。比如process對(duì)象、global(角色定位相當(dāng)于window對(duì)象)對(duì)象在瀏覽器里就沒(méi)有

---##### 關(guān)于請(qǐng)求的面試題

當(dāng)瀏覽器地址欄輸入www.baidu.com,敲下回車會(huì)發(fā)生什么?

1. 利用DNS域名解析系統(tǒng)進(jìn)行域名解析,將域名解析成IP 因?yàn)橛蛎皇且粋€(gè)別名,計(jì)算機(jī)只認(rèn)識(shí)IP,所以需要DNS解析一下

2. 查找ip對(duì)應(yīng)的主機(jī)服務(wù)器 如果是第一次訪問(wèn)該服務(wù)器,會(huì)向網(wǎng)絡(luò)供應(yīng)商(移動(dòng)、聯(lián)通...)請(qǐng)求

3. TCP的三次握手,經(jīng)過(guò)三次在客戶端和服務(wù)器之間傳遞報(bào)文,建立連接

4. 發(fā)起http請(qǐng)求,請(qǐng)求入口文件,后端接收到請(qǐng)求相關(guān)信息,返回入口文件

5. 解析入口文件,同時(shí)如果有資源請(qǐng)求繼續(xù)發(fā)送http請(qǐng)求..

.6. 入口文件渲染完成(TCP的四次揮手,斷開(kāi)連接)

---##### hello world

現(xiàn)在我們來(lái)創(chuàng)建一個(gè)hello.js文件

>ES6小知識(shí):const可以定義只讀常量readonly,let定義局部變量,只有用了這兩個(gè),就會(huì)形成塊級(jí)作用域。

// 引入http模塊 說(shuō)明Node給咱們內(nèi)置了很多模塊

const http = require("http")

//定義端口

const port = 3000

//定義域名信息 10.9.166.65

// 假設(shè)有一個(gè)大商城(服務(wù)器主機(jī)),商城里有很多商店(主機(jī)里可能有很多服務(wù)器),每一個(gè)商店都有自己的一個(gè)入口A1,A2(每一個(gè)服務(wù)器都有一個(gè)端口),大商場(chǎng)可能也有一些名字(域名或者IP)

// 域名和IP:域名只是為了方便用戶記憶,真正計(jì)算機(jī)識(shí)別的是IP,每一個(gè)網(wǎng)段主機(jī)都會(huì)擁有一個(gè)ip,

// 127.0.0.1回環(huán)地址對(duì)應(yīng)的域名是localhost,每個(gè)主機(jī)訪問(wèn)此地址的時(shí)候都是訪問(wèn)到的自己

const host = "127.0.0.1"

//創(chuàng)建服務(wù)(服務(wù)員) 傳入requestListener函數(shù),當(dāng)有客戶端訪問(wèn)的時(shí)候就會(huì)執(zhí)行

// req上保存的是此次訪問(wèn)的請(qǐng)求相關(guān)信息,一般用來(lái)做判斷...

//res是專門做出響應(yīng)的工具,有writeHead方法,statusCode屬性,setHeader方法,write方法,end方法

const server = http.createServer((req,res)=>{

console.log(req.url)//此次請(qǐng)求的地址,得到的就是整個(gè)請(qǐng)求地址中,域名端口后面的path路徑

console.log(req.method)//此次請(qǐng)求的方法

console.log(req.headers)//此次請(qǐng)求的請(qǐng)求頭信息例如cookie

// res.statusCode=200//設(shè)置響應(yīng)的狀態(tài)碼,為瀏覽器而設(shè)置,200成功 404

// res.setHeader("Content-Type","text/plain;charset=utf8")

//設(shè)置響應(yīng)頭

//content-type特別重要,告訴瀏覽器我給你返回的是什么東西,text/plain普通純文本,text/html,text/css,application/javascript

// res.writeHead(200,{'Content-Type':'text/html;charset=utf8'})

//是res.statusCode和res.setHeader的簡(jiǎn)寫方式

// res.write('海海帥嗎?')

//寫入響應(yīng)內(nèi)容,可以執(zhí)行多次,只能寫字符串? ? // res.write('帥')? ? // res.end('!!!')//通知前端響應(yīng)結(jié)束,其實(shí)在end里也可以寫入響應(yīng)內(nèi)容,但是end之后不能再write

res.writeHead(200,{'Content-Type':'text/html;charset=utf8'})

if(req.url=='/question'){

res.end(Math.random()<0.8?'帥':'還行吧')

}else if(req.url=='/random'){

res.end(Math.random()+'')

}else{

res.end('看看海海帥不帥來(lái)一個(gè)隨機(jī)數(shù)')?

? }

})

server.listen(port)


### 模塊和包管理工具

現(xiàn)在我們想做這樣一個(gè)事情,就是封裝一個(gè)專門在頁(yè)面中輸入hello——world的函數(shù),寫在我們的服務(wù)模塊上的話會(huì)影響我們的編程思路,因?yàn)闀?huì)比較亂,那么我們?cè)趺崔k呢?

其實(shí)這樣的問(wèn)題一直存在于我們的編程中,我們通常也就是分成單個(gè)的js文件來(lái)引入,但是這樣的話又要考慮命名沖突、依賴關(guān)系等等的問(wèn)題

nodeJs讓我們使用一套CommonJs規(guī)范來(lái)解決這些問(wèn)題:

按照規(guī)范來(lái)定義模塊,暴露接口,引用模塊,使用模塊

在node里的很多工具、包也都是在使用這個(gè)規(guī)范,也就是說(shuō)學(xué)習(xí)這個(gè)規(guī)范是很有必要的。

我們可以使用npm這個(gè)工具來(lái)安裝很多很多的包、工具,通過(guò)npm install方法來(lái)安裝,安裝好的內(nèi)容會(huì)放到node_modules文件夾里

下面我們來(lái)嘗試一下,

這里是我們的模塊:

//定義模塊

var util={};

util.sayHello=function(){

return 'hello nodeJs'

}

util.add=function(x,y){

return x+y;

}

//暴露接口

module.exports=util;

```

這里是我們使用模塊的地方:

```

var http=require('http');

var util=require('./4.util');//引入模塊

http.createServer(function(req,res){

res.writeHead(200,{'content-Type':'text/html;charset=utf-8'});

if(req.url!=='/favicon.ico'){

res.write(util.sayHello()+'');

//使用模塊

res.write(util.add(1,2)+'');res.end();

}

}).listen(3000);

```

有一個(gè)需要注意的地方,就是reswrite的時(shí)候需放入的是字符串

require引入模塊的時(shí)候,node內(nèi)置的模塊我們直接寫模塊名,自定義模塊的話我們要寫路徑,需要引入包的時(shí)候(用npm下載的,或者在node_modules文件夾里的),我們也直接寫模塊名就好。

使用module.exports暴露接口的時(shí)候我們可以暴露任何數(shù)據(jù)類型的任何東西,需要注意的是,不暴露的數(shù)據(jù)是模塊內(nèi)部數(shù)據(jù),不會(huì)在引入模塊的文件里使用。

module.exports其實(shí)是直接暴露出一個(gè)module的實(shí)例,并將實(shí)例賦值:

```

module.exports=util;

```

我們還可以這么做:

```

exports.sayHello=util.sayHello;

exports.add=util.add;

```

這樣的話我們并沒(méi)有重寫module的實(shí)例,只是為他添加了幾個(gè)方法;

在引入模塊的時(shí)候,可能我們的模塊有很多方法,我們也可以單個(gè)引入其中的幾個(gè):

```

var sayHello=require('./4.util').sayHello;

var add=require('./4.util').add;

```

這就是Commonjs的使用細(xì)節(jié),希望大家都要記住喲。

---

### NPM使用入門

npm 就是node package manager node的包管理工具

我們通過(guò)npm install 模塊 來(lái)安裝模塊,縮寫:npm i 模塊,注意,低版本的node可能需要npm init先來(lái)創(chuàng)建一個(gè)package.json文件,這也是我推薦的

卸載的話就是unintsall,全局安裝(大多是工具,例如gulp等) -g(全寫上是--global)

在在本地(當(dāng)前目錄上)安裝(大多是包)不需要加-g

使用npm list 可以查看現(xiàn)在安裝了的一些東西,npm list | grep 模塊 可以查看其中某個(gè)模塊的信息

使用npm info 模塊? 可以查看模塊的信息及歷史版本

使用npm install 模塊@版本號(hào) 可以來(lái)安裝對(duì)應(yīng)的版本的模塊包,原包就會(huì)被覆蓋

---

#### package.json相關(guān):

我們可以通過(guò)npm init來(lái)創(chuàng)建package.json文件,這個(gè)文件可以來(lái)管理我們的項(xiàng)目依賴的包的信息

devDependencies是開(kāi)發(fā)依賴,也就是只在開(kāi)發(fā)的時(shí)候使用的包 --save-dev (-D),depedencies是我們打包的時(shí)候依然使用的包--save (-S)

這個(gè)文件還有一個(gè)好處,就是使我們的項(xiàng)目有辨識(shí)性,我們?cè)谀承┣闆r下,需要將項(xiàng)目提交給某個(gè)地方或者共享給某人,這個(gè)時(shí)候我們不需要提交node——modules文件夾,只需要在那個(gè)地方執(zhí)行npm install 就可以安裝package.json里所有的包,使我們的項(xiàng)目可以繼續(xù)運(yùn)行

#### 源相關(guān):

我們可以全局安裝nrm這個(gè)工具來(lái)管理我們的源(就是下載地址),

nrm ls可以查看我們可以使用的源

nrm test可以來(lái)測(cè)試我們可以使用的源的速度

nrm use 源? 可以來(lái)切換我們使用的源.

#### 清楚緩存

有的時(shí)候我們因?yàn)橄螺d報(bào)錯(cuò)或者某種原因,需要重新下載的時(shí)候,結(jié)果依然報(bào)錯(cuò),我們排除掉網(wǎng)絡(luò)等原因后,可以嘗試通過(guò)執(zhí)行npm cache clear 來(lái)清除掉npm的緩存。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 在現(xiàn)在的前端開(kāi)發(fā)中,前后端分離、模塊化開(kāi)發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開(kāi)始...
    Charlot閱讀 5,497評(píng)論 1 32
  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無(wú)需寫一大堆繁雜的配置參數(shù),API也非常簡(jiǎn)單,學(xué)...
    依依玖玥閱讀 3,185評(píng)論 7 55
  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無(wú)需寫一大堆繁雜的配置參數(shù),API也非常簡(jiǎn)單,學(xué)...
    井皮皮閱讀 1,324評(píng)論 0 10
  • 前言 眾所周知目前比較火的工具就是gulp和webpack,但webpack和gulp卻有所不同,本人兩者的底層研...
    cduyzh閱讀 1,392評(píng)論 0 13
  • gulpjs是一個(gè)前端構(gòu)建工具,與gruntjs相比,gulpjs無(wú)需寫一大堆繁雜的配置參數(shù),API也非常簡(jiǎn)單,學(xué)...
    小裁縫sun閱讀 952評(píng)論 0 3