## 前端開(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的緩存。