Node.js

1、終端基本使用

打開應(yīng)用

  • notepad 打開記事本
  • mspaint 打開畫圖
  • calc 打開計算機
  • write 寫字板
  • sysdm.cpl 打開環(huán)境變量設(shè)置窗口

常用命令

  • md 創(chuàng)建目錄
  • rmdir(rd) 刪除目錄,目錄內(nèi)沒有文檔。
  • echo on > a.txt 創(chuàng)建空文件
  • echo 內(nèi)容 > a.txt 往文件里寫內(nèi)容
  • echo 內(nèi)容 >> a.txt 往文件里追加內(nèi)容,同時也會覆蓋以前的
  • del 刪除文件
  • rm 文件名 刪除文件
  • cat 文件名 查看文件內(nèi)容
  • cat > 文件名 向文件中寫上內(nèi)容

2、Node.js開發(fā)環(huán)境搭建

  • Node.js 介紹
    • Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境
    • Node.js 使用了一個事件驅(qū)動、非阻塞式 I/O 的模型,使其輕量又高效
    • Node.js 的包管理器 npm,是全球最大的開源庫生態(tài)系統(tǒng)
    • javascript 是腳本語言,需要解析器才能執(zhí)行,瀏覽器就充當(dāng)了解析器
    • 在Chrome中,解析器就是 V8 引擎,將 javascript 轉(zhuǎn)換成 機器碼
    • V8 引擎是開源的,由 C++ 語言編寫,性能高
    • Node.js 高性能,事件驅(qū)動,非阻塞,生態(tài)圈很好
  • Node.js 普通安裝
    • 官網(wǎng) 下載安裝即可,很小不到20M!
    • 驗證是否成功,命令行輸入 node -v 顯示版本號如 v8.11.4
    • 按提示升級 npm,Update available 5.6.0 → 6.4.1, npm i -g npm
  • Node.js多版本安裝方式
    • 卸載已有的Node.js
    • 下載nvm
    • 在C盤創(chuàng)建目錄dev
    • 在dev目中中創(chuàng)建兩個子目錄nvm和nodejs
    • 并且把nvm包解壓進去nvm目錄中
    • 在install.cmd文件上面右鍵選擇【以管理員身份運行】
    • 打開的cmd窗口直接回車會生成一個settings.txt文件,修改文件中配置信息
    • 配置nvm和Node.js環(huán)境變量
      • NVM_HOME:C:\dev\nvm
      • NVM_SYMLINK:C:\dev\nodejs
    • 把配置好的兩個環(huán)境變量加到Path中
  • nvm常用的命令
    • nvm list 查看當(dāng)前安裝的Node.js所有版本
    • nvm install 版本號 安裝指定版本的Node.js
    • nvm uninstall 版本號 卸載指定版本的Node.js
    • nvm use 版本號 選擇指定版本的Node.js

3、全局對象

  • 全局對象

    • 不用導(dǎo)入,直接使用的對象
    • 官方文檔
    • Buffer 類,用于處理二進制數(shù)據(jù)
    • console,用于打印 stdout 和 stderr
    • global, 全局的命名空間對象
    • process,進程對象
    • setTimeout(callback, delay[, ...args])
    • setInterval(callback, delay[, ...args])
    • setImmediate(callback[, ...args])
    • clearTimeout(timeoutObject)
    • clearInterval(intervalObject)
    • clearImmediate(immediateObject)
  • 以下變量雖然看起來像全局變量,但實際上不是

    • 全局變量在所有模塊中均可使用
    • 以下對象作用域只在模塊內(nèi),詳見 module文檔
    • __dirname
    • __filename
    • exports
    • module
    • require()
  • 運行 .js 腳本文件

    • node app 或者 node app.js
  • 實踐代碼

    console.log('hello world');
    
    setTimeout(function () {
        console.log("3 seconds have passed 2");
    }, 3000);
    
    // 箭頭函數(shù),es6的寫法
    setTimeout(() => {
        console.log("3 seconds have passed 1");
    }, 3000);
    
    // 每間隔2秒不斷執(zhí)行
    setInterval(function () {
        console.log("2 seconds have passed");
    }, 2000);
    
    
    var time = 0
    var timer = setInterval(function () {
        time += 2;
        console.log(time + " seconds have passed");
        if (time > 6) {
            clearInterval(timer);
            console.log("clearInterval")
        }
    }, 2000)
    
    // 輸出當(dāng)前目錄 和 帶絕對路徑的文件名
    console.log(__dirname)
    console.log(__filename)
    
    console.log('end')
    console.dir(global)
    

4、回調(diào)函數(shù)

function sayHi() {
    console.log('Hi')
}

sayHi() // 調(diào)用函數(shù)

// 將匿名函數(shù)賦給變量
var sayBye = function (name) {
    console.log(name + ' Bye')
}

sayBye()

// 第一個參數(shù)是函數(shù)
function callFunction(fun, name) {
    fun(name)
}

callFunction(sayBye, 'able')
// 或者
callFunction(function (name) {
    console.log(name + ' Bye')
}, 'able')

5、模塊化

傳統(tǒng)非模塊化開發(fā)有如下的缺點:

? 1、命名沖突

? 2、文件依賴

前端標(biāo)準(zhǔn)的模塊化規(guī)范:

? 1、AMD - requirejs

? 2、CMD - seajs //阿里的

服務(wù)器端的模塊化規(guī)范:

? 1、CommonJS - Node.js

模塊化相關(guān)的規(guī)則:

? 1、如何定義模塊:一個js文件就是一個模塊,模塊內(nèi)部的成員都是相互獨立

? 2、模塊成員的導(dǎo)出和引入

? 模塊成員的導(dǎo)出最終以module.exports為準(zhǔn)

? 如果要導(dǎo)出單個的成員或者比較少的成員,一般我們使用exports導(dǎo)出;

? 如果要導(dǎo)出的成員比較多,一般我們使用module.exports的方式

? 這兩種方式不能同時使用

? exports與module的關(guān)系:

? module.exports = exports = {};

module 對象

  • 每個文件都被視為獨立的模塊
  • 每個模塊中,module 指向表示當(dāng)前模塊的對象的引用
  • module 實際上不是全局的,而是每個模塊本地的
  • module.exports 導(dǎo)出模塊內(nèi)的對象,方便其他對象引用
  • require() 引入模塊
  • 當(dāng) Node.js 直接運行一個文件時,require.main 會被設(shè)為它的 module
  • 可以通過 require.main === module 來判斷一個文件是否被直接運行
  • module 提供了一個 filename 屬性(通常等同于 __filename)
  • 可以通過檢查 require.main.filename 來獲取當(dāng)前應(yīng)用程序的入口點
//例1
//導(dǎo)出 03.js
var sum = function(a,b){
    return parseInt(a) + parseInt(b);
}
exports.sum = sum;
//引入
var module = require('./03.js');

var ret = module.sum(12,13);
console.log(ret);    //輸出  25
//例2
//導(dǎo)出 03.js
var sum = function(a,b){
    return parseInt(a) + parseInt(b);
}
module.exports = sum;
// 引入
var module = require('./03.js');
var ret = module(12,13);
console.log(ret);   //輸出  25
//例3
//導(dǎo)出
var flag = 123;
global.flag = flag;  

//引入
require('./07');
console.log(global.flag);   //輸出 123
//例4
var counter = function(arr){
    return "There are" + arr.length +"element in the array";
}

var adder = function(a,b){
    return `the sum of the 2 numnber is ${a+b}`;
}

var pi = 3.14;

// module.exports.counter = counter;
// module.exports.adder = adder;
// module.exports.pi = pi;
// 或者
module.exports = {
    counter: counter,
    adder:adder,
    pi:pi
}

//引入
var stuff = require('./9');

console.log(stuff.counter(['1','2','3'])); //輸出 There are3element in the array
console.log(stuff.adder(5,5));   //輸出 the sum of the 2 numnber is 10
console.log(stuff.pi);  // 輸出 3.14

注意:已經(jīng)加載的模塊會緩存。

? 模塊文件的后綴3種情況:.js .json .node

? 上述三種模塊的加載優(yōu)先級(不加文件后綴時的優(yōu)先級):.js -> .json -> .node

6、buffer基本操作

Buffer對象是Node處理二進制數(shù)據(jù)的一個接口。它是Node原生提供的全局對象,可以直接使用,不需要require(‘buffer’)。

  • 實例化
    • Buffer.from(array)
    • Buffer.from(string)
    • Buffer.alloc(size)
  • 功能方法
    • Buffer.isEncoding() 判斷是否支持該編碼
    • Buffer.isBuffer() 判斷是否為Buffer
    • Buffer.byteLength() 返回指定編碼的字節(jié)長度,默認utf8
    • Buffer.concat() 將一組Buffer對象合并為一個Buffer對象
  • 實例方法
    • write() 向buffer對象中寫入內(nèi)容
    • slice() 截取新的buffer對象
    • toString() 把buf對象轉(zhuǎn)成字符串
    • toJson() 把buf對象轉(zhuǎn)成json形式的字符串

7、事件(events)

  • 多數(shù) Node.js 核心 API 都采用異步事件驅(qū)動架構(gòu)
  • 所有能觸發(fā)事件的對象都是 EventEmitter 類的實例
  • 事件名稱通常是駝峰式的字符串
  • 實踐代碼
//例1    
// 導(dǎo)入事件庫
var events = require('events');

// 新建事件對象
var myEmitter = new events.EventEmitter();

// 綁定事件,事件名稱叫做someEvent,后面是事件觸發(fā)的回調(diào)函數(shù)
myEmitter.on('someEvent',function(message){
    console.log(message);
})
// 手動觸發(fā)
myEmitter.emit('someEvent','the event was emmitted');  //the event was emmitted
//例2   (給對象一個事件)
var events = require('events');// 導(dǎo)入事件庫
var util = require('util');    // 導(dǎo)入工具庫

var Person = function(name){ //定義一個對象
    this.name = name;
}
// inherits是繼承的意思,讓Person類繼承事件對象的屬性
util.inherits(Person,events.EventEmitter);

// 定義三個對象
var xiaoming = new Person('xiaoming');
var lili = new Person('lili');
var lucy = new Person('lucy');

var persons = [xiaoming,lili,lucy];

// 循環(huán)數(shù)組,每個對象都綁定一個事件
persons.forEach(function(persons){
    persons.on('speak',function(message){
        console.log(persons.name +' said  '+ message);
    })
})
// 觸發(fā)
xiaoming.emit('speak','hi');
lili.emit('speak','i want a apple');

// 注意,要讓對象使用事件,就讓對象繼承那個事件庫的對象就行了,也就是
// events.EventEmitter

8、讀寫文件(同步和異步)

//例1
var fs = require('fs');   //文件的一個庫

var readMe = fs.readFileSync("readMe.txt","utf8");  //參數(shù):文件名,編碼
console.log(readMe);  // you read me!

fs.writeFileSync("writeMe.txt","這是寫入的");  //參數(shù):文件名,寫入的東西
// 以上部分是同步執(zhí)行情況
// node.js執(zhí)行JavaScript的時候是單線程的,如果讀寫文件很耗時,他就會阻塞

注意:IO操作是很耗時的,它不能阻塞主線程,應(yīng)該發(fā)起一個新的線程去執(zhí)行它

? noejs中異步處理操作,異步的操作都要加回調(diào)函數(shù)

//例2
// 解決辦法,用異步
var fs = require('fs');

var readMe = fs.readFile("readMe.txt","utf8",function(err,data){
    console.log(data);     //you read me!
    fs.writeFile("writeMe.txt","寫入的內(nèi)容",function(){
        console.log('writeMe has finished!');
    })
})

console.log("finished");    //這個比上面那句先執(zhí)行
// why
/*
    第二條語句是一個異步的事件,異步的IO操作,nodejs在執(zhí)行JavaScript的時候
    是單線程的,語句還是一行一行往下執(zhí)行,為什么這里會先執(zhí)行最后一句呢?這是因為
    nodejs維護了一個事件隊列,執(zhí)行第二句的時候,會在事件隊列那里注冊一個事件,告訴
    這個事件隊列我將要去讀一個文件,但是這個回調(diào)函數(shù)沒有被馬上執(zhí)行,這個操作是
    瞬間完成的。完成之后他就會執(zhí)行主線程的第三個語句。當(dāng)主線程空閑之后,它就會
    去找事件隊列里面的事件,把它取出來,然后發(fā)起一個線程執(zhí)行,執(zhí)行成功后,它就
    告訴主線程我已經(jīng)成功了,你來執(zhí)行我吧。所以這里先執(zhí)行的是主線程,然后執(zhí)行的
    是異步操作里面的回調(diào)函數(shù)。

    注意:IO操作是很耗時的,它不能阻塞主線程,應(yīng)該發(fā)起一個新的線程去執(zhí)行它
          noejs中異步處理操作,異步的操作都要加回調(diào)函數(shù)
*/
 
//例3
var fs = require('fs');
// 異步刪除文件
fs.unlink("writeMe.txt", function () {
    console.log("delete writeMe.txt file");
})

// 同步創(chuàng)建和刪除目錄
fs.mkdirSync('stuff');
fs.rmdirSync('stuff');

// 異步創(chuàng)建目錄,但是這種遞歸回調(diào),嵌套太多會出現(xiàn)問題,以后再說解決辦法
fs.mkdir('stuff', function () {
    fs.readFile('readMe.txt','utf8',function(err,data){
        fs.writeFile('./stuff/writeMe.txt',data,function(){
            console.log('copy successfully');
        })
    })
});

9、流和管道

  • 流(stream)
    • 處理流式數(shù)據(jù)的抽象接口
    • stream 模塊提供了一些基礎(chǔ)的 API,用于構(gòu)建實現(xiàn)了流接口的對象
    • 流可以是可讀的、可寫的、或是可讀寫的,所有的流都是 EventEmitter 的實例
    • 處理數(shù)據(jù)通過緩存可以提高性能
  • 管道
    • 使用管道,代碼量更少
    • myReadStream.pipe(myWriteStream)
//例1
var fs = require('fs');
// 創(chuàng)建一個輸入流
var myReadStream = fs.createReadStream(__dirname+'/readMe.txt');
// 流是一個事件的實例,擁有事件的一些特性,它可以綁定一些監(jiān)聽函數(shù)
myReadStream.on('data',function(chunk){
    console.log('new chunk received');  //new chunk received
    console.log(chunk);    //<Buffer 79 6f 75 20 72 65 61 64 20 6d 65 21>
})
// 性能提高的原因是文件分成buffer了
//例2
var fs = require('fs');
// 創(chuàng)建一個讀的流
var myReadStream = fs.createReadStream(__dirname+'/readMe.txt');
//創(chuàng)建一個寫入的流
var myWriteStream = fs.createWriteStream(__dirname+'/writeMe.txt');

//設(shè)置編碼
myReadStream.setEncoding('utf8');

var data = ""
// 接收數(shù)據(jù)時用的監(jiān)聽函數(shù)
myReadStream.on('data',function(chunk){
    data += chunk;
    myWriteStream.write(chunk);//這里寫入內(nèi)容
})
//接受完數(shù)據(jù)之后用的
myReadStream.on('end',function(){
    console.log(data);
})
//例3
var fs = require('fs');
// 創(chuàng)建一個讀的流
var myReadStream = fs.createReadStream(__dirname+'/readMe.txt');
//創(chuàng)建一個寫入的流
var myWriteStream = fs.createWriteStream(__dirname+'/writeMe.txt');

var writeData = "hello world";

myWriteStream.write(writeData,'utf8');   //向文件中寫入 "hello world"  
myWriteStream.end();
myWriteStream.on('finish',function(){
    console.log('finished');
})

以上三例是用流來寫入或讀出文件

//管道

var fs = require('fs');
// 創(chuàng)建一個讀的流
var myReadStream = fs.createReadStream(__dirname+'/readMe.txt');
//創(chuàng)建一個寫入的流
var myWriteStream = fs.createWriteStream(__dirname+'/writeMe.txt');

// 直接將 myReadStream內(nèi)容 寫入 myWriteStream
myReadStream.pipe(myWriteStream);
var crypto = require('crypto');  //加密
var fs = require('fs');
var zlib = require('zlib');   //壓縮

var password = new Buffer(process.env.PASS || 'password');
var encryptStream = crypto.createCipher('aes-256-cbc',password);

var gzip = zlib.createGzip();
var readStream = fs.createReadStream(__dirname+"/readMe.txt");
var writeStream = fs.createWriteStream(__dirname+"/out.gz");

// 壓縮
readStream
    .pipe(encryptStream)
    .pipe(gzip)
    .pipe(writeStream)
    .on('finish',function(){
        console.log('done');
    });
//解壓縮
var crypto = require('crypto');  //加密
var fs = require('fs');
var zlib = require('zlib');   //解壓縮

var password = new Buffer(process.env.PASS || 'password');
var decryptStream = crypto.createDeCipher('aes-256-cbc',password);

var gzip = zlib.createGunzip();
var readStream = fs.createReadStream(__dirname+"/out.gz");

// 解壓縮
readStream
    .pipe(gzip)
    .pipe(decryptStream)
    .pipe(process.stdout)
    .on('finish',function(){
        console.log('done');
    });

10、http模塊,web服務(wù)器

下面幾個是響應(yīng)一個純文本給客戶端

var http = require('http');

var server = http.createServer(function(request,response){
    console.log("Request received");
    response.writeHead(200,{'Content-Type':'text/plain'});
    response.write('Hello from out application');
    response.end();
})

server.listen(3000);
console.log('Server started on locahost port 3000');
1.png

2.png
//把上面的  server.listen(3000);改成下面這句
server.listen(3000,'127.0.0.1');
3.png
//改用 request 表達式
var http = require('http');

// request表達式
var onRequest = function(request,response){
    console.log("Request received");
    response.writeHead(200,{'Content-Type':'text/plain'});
    response.end('Hello from out application');
}

var server = http.createServer(onRequest);

server.listen(3000,'127.0.0.1');
console.log('Server started on locahost port 3000');

11、web服務(wù)器響應(yīng)json

var http = require('http');

// request表達式
var onRequest = function(request,response){
    console.log("Request received");
    // 這里改為響應(yīng)json的
    response.writeHead(200,{'Content-Type':'application/json'});
    var myObj = {
        name:'hfisdwc',
        job:'programmer',
        age:27
    }
    response.end(JSON.stringify(myObj));  //將對象轉(zhuǎn)換成json字符串,寫入response中
}

var server = http.createServer(onRequest);

server.listen(3000,'127.0.0.1');
console.log('Server started on locahost port 3000');
4.png

序列化:把它轉(zhuǎn)成字符串 stringify

反序列化:把字符串轉(zhuǎn)成對象 parse

  • JSON對象
    • 字符串必須使用雙引號表示,不能使用單引號
    • 對象的鍵名必須放在雙引號里面
    • 數(shù)組或?qū)ο笞詈笠粋€成員的后面,不能加逗號
    • JSON對象是 JavaScript 的原生對象,用來處理 JSON 格式數(shù)據(jù)
    • JSON.stringify方法用于將一個值轉(zhuǎn)為 JSON 字符串
    • JSON.parse方法用于將 JSON 字符串轉(zhuǎn)換成對應(yīng)的值

12、web服務(wù)器響應(yīng)HTML

var http = require('http');
var fs = require('fs');

// request表達式
var onRequest = function(request,response){
    console.log("Request received");
    // 這里改為響應(yīng)html的
    response.writeHead(200,{'Content-Type':'text/html'});
    var myReadStream = fs.createReadStream(__dirname+'/index.html','utf8');
    myReadStream.pipe(response);
}

var server = http.createServer(onRequest);

server.listen(3000,'127.0.0.1');
console.log('Server started on locahost port 3000');

13、模塊化思想組織代碼

var http = require('http');
var fs = require('fs');

function startServer() {
    // request表達式
    var onRequest = function (request, response) {
        console.log("Request received");
        // 這里改為響應(yīng)html的
        response.writeHead(200, {
            'Content-Type': 'text/html'
        });
        var myReadStream = fs.createReadStream(__dirname + '/index.html', 'utf8');
        myReadStream.pipe(response);
    }

    var server = http.createServer(onRequest);

    server.listen(3000, '127.0.0.1');
    console.log('Server started on locahost port 3000');
}

// 導(dǎo)出
exports.startServer = startServer;
//導(dǎo)入
var server = require('./server');
server.startServer();

14、web服務(wù)器路由

var http = require('http');
var fs = require('fs');

function startServer() {
    var onRequest = function (req, res) {
        console.log('request received ' + req.url)

        if (req.url === '/' || req.url === '/home') {
            res.writeHead(200, { 'Content-Type': 'text/html' })
            fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(res)
        } else if (req.url === '/review') {
            res.writeHead(200, { 'Content-Type': 'text/html' })
            fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(res)
        } else if (req.url === '/api/v1/records') {
            res.writeHead(200, { 'Content-Type': 'application/json' })
            var jsonObj = {
                name: 'able'
            }
            res.end(JSON.stringify(jsonObj))
        } else {
            res.writeHead(200, { 'Content-Type': 'text/html' })
            fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(res)
        }
    }
    var server = http.createServer(onRequest)
    server.listen(3000)
    console.log('server started on http://127.0.0.1:3000')
}

// 導(dǎo)出
exports.startServer = startServer;

重構(gòu)上面的路由代碼:

  • 將路由、處理函數(shù)和主程序分離,單獨存放
  • 分工明確,各司其職,方便管理
//server.js
var http = require('http')
var url = require('url')   //url庫
var querystring = require('querystring')

function startServer(route, handle) {
    var onRequest = function (req, res) {
        console.log('request received ' + req.url)
        var pathname = url.parse(req.url,true).pathname

        var data = ""
        req.on("error", function (err) {
            console.error(err)
        }).on("data", function (chunk) {
            data += chunk
        }).on("end", function () {
            if (req.mothod === "POST") {
                if (data.length > 1e6) {
                    req.connection.destroy() // 如果數(shù)據(jù)很大,就斷開
                }
                route(handle, pathname, res, querystring.parse(data))
            } else {
                var params = url.parse(req.url, true).query
                route(handle, pathname, res, params)
            }
        })
        // 或者
        // var data = []
        // data.push(chunk)
        // data = Buffer.concat(data).toString()

    }
    var server = http.createServer(onRequest)
    server.listen(3000)
    console.log('server started on http://127.0.0.1:3000')
}

module.exports.startServer = startServer
//router.js
fs = require('fs')

function route(handle, pathname, res, params) {
    console.log('Routing a request for ' + pathname)
    if (typeof handle[pathname] === 'function') {
        handle[pathname](res, params)
    } else {
        console.log('No handle for ' + pathname)
        res.writeHead(200, { 'Content-Type': 'text/html' })
        fs.createReadStream(__dirname + '/404.html', 'utf8').pipe(res)
    }
}

module.exports.route = route
//handler.js
var fs = require('fs')

function home(res) {
    console.log('home')
    res.writeHead(200, { 'Content-Type': 'text/html' })
    fs.createReadStream(__dirname + '/index.html', 'utf8').pipe(res)
}

function review(res) {
    console.log('review')
    res.writeHead(200, { 'Content-Type': 'text/html' })
    fs.createReadStream(__dirname + '/review.html', 'utf8').pipe(res)
}

function api_records(res, params) {
    console.log('api_records')
    res.writeHead(200, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify(params))
}

module.exports = {
    home: home,
    review: review,
    api_records: api_records
}
//app.js
var server = require('./server')
var router = require('./router')
var handler = require('./handler')

var handle = {}
// key是路徑,值是處理函數(shù)
handle['/'] = handler.home
handle['/home'] = handler.home
handle['/review'] = handler.review
handle['/api/v1/records'] = handler.api_records

server.startServer(router.route, handle)

15、web服務(wù)器使用get或post請求發(fā)送數(shù)據(jù)

有兩種方式:通過地址欄和表單

地址欄是用get方法,表單是post方法。因為地址欄的數(shù)據(jù)是暴露出去的,所以通常用于查詢數(shù)據(jù),而通過表單傳遞數(shù)據(jù)一般用于提交一些信息。

querystring - 查詢字符串

  • var querystring = require('querystring')
  • querystring.parse(data) 把一個 URL 查詢字符串 str 解析成一個鍵值對的集合
// 接收請求數(shù)據(jù),然后處理,查看request 類型
var data = ""
req.on("error", function (err) {
    console.error(err)
}).on("data", function (chunk) {
    data += chunk
}).on("end", function () {
    if (req.mothod === "POST") {
        if (data.length > 1e6) {
            req.connection.destroy() // 如果數(shù)據(jù)很大,就斷開
        }
        route(handle, pathname, res, querystring.parse(data))
    } else {
        var params = url.parse(req.url, true).query
        route(handle, pathname, res, params)
    }
})
// 或者
// var data = []
// data.push(chunk)
// data = Buffer.concat(data).toString()

16、包管理器 npm

# Or alias it in .bashrc or .zshrc
echo '\n#alias for npm\nalias npm="npm --registry=https://registry.npm.taobao.org \
  --cache=$HOME/.npm/.cache/npm \
  --disturl=https://npm.taobao.org/dist \
  --userconfig=$HOME/.npmrc"' >> ~/.zshrc && source ~/.zshrc
  • yarn 也是包管理器,更快下載速度

17、package.json 文件

  • 記錄項目中使用的包名,發(fā)布時不用包內(nèi)容了,只要名稱就行
  • npm init 提問式初始化項目信息,生成package.json文件,-y 全部默認
  • npm install --save xxx安裝的同時,將信息寫入package.json
  • npm install --save-dev xxx安裝的同時,將信息寫入package.json中的dev開發(fā)依賴
  • npm view moduleNames 查看node模塊的package.json文件夾
  • npm run start 啟動包,執(zhí)行 package.json scripts 中的 start 命令,還有 stop restart test
  • npm install 安裝 package.json 中記錄的包

18、nodemon監(jiān)控文件并重啟服務(wù)

  • nodemon 用來監(jiān)視應(yīng)用中的任何文件更改并自動重啟服務(wù)
  • 非常適合用在開發(fā)環(huán)境中,方便啊,不用手動操作了
  • 全局安裝 npm install -g nodemon
  • 本地安裝 npm install --save-dev nodemon
  • 啟動應(yīng)用 nodemon [your node app]
  • 獲取修改 package.json 中的啟動腳本,添加nodemon app.js, 用 npm start 直接啟動,方便
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 個人入門學(xué)習(xí)用筆記、不過多作為參考依據(jù)。如有錯誤歡迎斧正 目錄 簡書好像不支持錨點、復(fù)制搜索(反正也是寫給我自己看...
    kirito_song閱讀 2,648評論 1 37
  • 1.描述Node.js 是一個基于 Chrome V8 引擎的 JavaScript 運行環(huán)境。使用了一個事件驅(qū)動...
    帥哥_刷哥閱讀 367評論 0 0
  • topics: 1.The Node.js philosophy 2.The reactor pattern 3....
    宮若石閱讀 1,234評論 0 1
  • # 模塊機制 node采用模塊化結(jié)構(gòu),按照CommonJS規(guī)范定義和使用模塊,模塊與文件是一一對應(yīng)關(guān)系,即加載一個...
    RichRand閱讀 2,731評論 0 3
  • 西點軍校 華為的魂是客戶。 “堅持是這個時代的奢侈品”這是華為在發(fā)布一款手機時的廣告語。 我在華為學(xué)到了什么? 0...
    紅顏江山閱讀 230評論 0 0

友情鏈接更多精彩內(nèi)容