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');


//把上面的 server.listen(3000);改成下面這句
server.listen(3000,'127.0.0.1');

//改用 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');

序列化:把它轉(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ù)一般用于提交一些信息。
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
- npm 官網(wǎng)
-
npm install -g xxx全局安裝可執(zhí)行文件,當(dāng)作命令行工具 - 使用國內(nèi)源,解決慢的問題
# 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 直接啟動,方便