『壹』 一個後端人員學前端技術的日記(一)開發環境
網上了解了好一陣,好傢伙,前端技術完全自成體系,跟後端一樣復雜了,什麼路由,什麼MVC,什麼編譯打包,什麼依賴下載,各種後端用詞在前端也都適用了,哎,太難了。
一、學習渠扒歲道
1. 中文官網: https://cn.vuejs.org/
開發工具使用火狐,因為谷歌用不了擴展,當然你可能會有辦法的。
用火狐瀏覽器打開: https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/
2. 官方文檔 : https://v3.cn.vuejs.org/guide/introction.html
二、環境安裝
首先要注意芹基的是,涉及使用cmd命令行執行的,如npm命令等,最好用管理員許可權打開cmd,否則說不準後面會出現莫名其妙的錯誤。
1. 安裝nodejs,這個是可以運行js代碼的服務端環境,方便本地運行或熱部署,這個nodejs包含了npm組件(依賴包管理工具,支持下載、運行、編譯、打包等等)
下載地址: https://nodejs.org/zh-cn/
我本地安裝的版本是 node-v10.16.3-win-x64,一般安裝在 D:Program Files。
2. 安裝cnpm組件,為了下載安裝包和依賴包更快一點,最好用先安裝國內鏡像支持,這個組件包含了包含npm大部分功能。
3. 安裝Vue/CLI組件,你可以直接使用npm安裝,或者安裝Vue的CLI,就是腳手架工具,裡麵包含了Vue本身,建議直接安裝這個,省的麻煩。
官網建議Vue3的使用Vue CLI v4.5+,如果版本有問題或升級版本,可以直接去這里刪除,全局的庫目錄在 D:Program Files ode-v10.16.3-win-x64 ode_moles。
4. 創建項目。先命令行轉到你要放置項目的目錄,執行以下命令。
然後窗口會讓你選擇是Vue2版本還是Vue3版本的,它還包含默認安裝(babel, eslint),我當然選擇最新的Vue3安裝。
windows下安裝注意別用powershell或者git-bash,直接用cmd命令行就好。
結尾出現以下提示,說明你安裝成功了。
知識記錄1:如果你出現以下問題:
原因是:執行npm命令時沒有管理員許可權, 用管理員許可權打開cmd, 然後再執行npm相關命令即可。
知識記錄2:如果你有Vue2,想升級Vue3的最新版本,可操作如下:
5. 額外介紹下,你不一定使用vue腳手架創建vue項目,你還可以使用vite組件創建項目。
官網: https://github.com/vitejs/vite
注意:vite當前只支持vue3.x
名詞注釋:
腳手架:就是標準的、常見的一種春首睜項目目錄安排規范。
babel: js的編譯器,用了它你就可以像後端開發語言一樣對源碼進行編譯打包了。
eslint:一種js的代碼檢測工具。
『貳』 怎麼在阿里雲伺服器里使用nodejs環境
首次登錄雲伺服器,要先進行用戶設置。
用戶設置
首先用passwd命令修改超級管理員root密碼。
1
$ passwd
根據提示連續輸入兩次密碼,很簡單吧。
接著,要新建一個普通的管理賬號並設置密碼,用於日常的系統管理。
1
2
$ useradd user1
$ passwd user1
將用戶添加進管理組,以便於統一管理管理員的許可權。
1
$ usermod -a -G wheel user1
設置新用戶的sudo許可權。
1
$ visudo
執行visudo命令實際上編輯的是/etc/sudoers文件。 找到 root ALL=(ALL:ALL) ALL 這行,並下面添加一行
1
user1 ALL=(ALL:ALL) ALL保存退出,以後就可用用sudo命令執行管理操作了。
修改主機名
每台伺服器都有自己的名字,一般web伺服器會用網站的域名來做主機名。 [用戶名@主機名 ~]$
1
2
$ hostname "www.chufa.la"
$ vi /etc/sysconfig/networkHOSTNAME=www.chufa.la
保存,並退出編輯,下次等登譽搏入伺服器就能看到修改的主機名字了。
SSH配置
將ssh的埠22改掉,另外,禁止root通過ssh登錄伺服器,並允許新建的普通管理員登錄。
1
$ vi /etc/ssh/sshd_config
找到 # Port 22 ,去掉#並將22修改為1025到65536 之間的沒被用到的埠號。 找到下面一行慶族祥,並去掉注釋符。
1
# PermitRootLogin yes在配置文件里添加
1
AllowUsers user1
保存後,退出文件編輯。 重啟sshd
1
$ service sshd restart
下次登錄,就要用新設定的埠號登錄了。
1
$ ssh user1@ip -p port
掛載數據盤
為數據盤建立交換分區和普通分區,並掛載到系統。 首先查看查看數據盤
1
$ fdisk -l
確認數據盤為 /dev/xvdb 接著,對數據盤進行分區操作,
1
$ fdisk -S 56 /dev/xvdb
輸入m可以查看幫助。 這里直接鍵入n新建第一個擴展分區,接著輸入p建立立基本分區,輸入要建立的分區號1,起始簇保持默認,結束簇的位置輸入 +2G (一般擴展分區的大小為內存的兩倍)。 然後,重復上面的步驟,將剩下的分為數據盤,注意第二個分區的分區號為2。
格式化分區
1
2
$ mkswap /dev/xvdb1
$ mkfs.ext4 /dev/xvdb2
啟用swap分區
1
$ swapon /dev/xvdb1
將數據盤的第二個分區,掛載到新建的 /data 目錄。
1
$ mkdir /data
修改fstab文件,保證重啟系統後自動掛載。
1
$ vi /etc/fstab
添加
1
2
/dev/xvdb1 swap swap defaults 0 0
/dev/xvdb2 /data ext4 defaults 0 0
保存文件,並退出編輯,下次啟動系統就能自動掛載數據盤了。
執行掛載命令,可以立即看到掛載的硬碟。
1
$ mount -a
軟體安裝 Nginx Mongo Node
我習慣於多個node進程共享80埠,用nginx反向代理到不同的node服務上去。 安裝nginx。 新建yum倉庫配置文件。
1
$ vi /etc/yum.repos.d/nginx.repo
內容如下穗野:
1
2
3
4
5
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/$basearch/
gpgcheck=0
enabled=1保存文件,並退出編輯。
執行.
1
$ yum install nginx安裝mongodb
1
$ vi /etc/yum.repos.d/mongodb.repo
文件內容
1
2
3
4
5
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
gpgcheck=0
enabled=1保存文件,並退出編輯。
執行
1
$ yum install mongodb-org
安裝Node和NPM
1
$ sudo yum install nodejs npm
至此,伺服器環境就搭建好了。
『叄』 nodejs request中options選項中的form和body分別表示什麼含義
POST請求
varrequest=require('request');
varurl="請求url";
varrequestData="需要傳輸的數據";
request({
url:url,
method:"POST",
json:true,
headers:{
"content-type":"application/json",
},
body:JSON.stringify(requestData)
},function(error,response,body){
if(!error&&response.statusCode==200){
console.log(body)//請求成功的處理邏輯
}
});
POST form格式上傳數據
request.post(
{url:'',
form:{key:'value'}
},
function(error,response,body){
if(!error&&response.statusCode==200){
console.log(body)//請求成功的處理邏輯
}
})
『肆』 web解題用nodejs寫的登錄站點
答:您好,要寫一個登錄站點,使用Node.js編寫,最少游昌褲200字最多500字,並且要回答完整,不要出現重復,回答您的問題。
首先,您需要安裝Node.js,安裝完成後,您可以使用Node.js開發登錄站點。其次,您需要編寫登錄站點的前端代碼,包括HTML、CSS和JavaScript,以及一些框架,如jQuery等,來實現登錄站點的神簡功能。最後,您需要編寫後端代碼,使用Node.js來實現登錄站點的功能,包括處理用戶輸入的數據,連接資料庫,以及實現其他功能。
此外,您還需要注意,登錄站點的代碼應該盡可能的簡潔,不要出現重復的代碼,並且應該盡可能的注釋,以便以後的維護和修改。
總之迅坦,編寫一個登錄站點,使用Node.js編寫,最少200字最多500字,並且要回答完整,不要出現重復,回答您的問題,需要您安裝Node.js,編寫前端代碼,編寫後端代碼,以及注意代碼的簡潔性和注釋。
『伍』 nodejs 承載 多少 websocket
首先是協議的升級,這個比較簡單,就簡述一下:當在客戶端執行new
Websocket("ws://XXX.com/")的時候,客戶端就會發起請求報文進行握手申請,報文中有個很重要的key就是Sec-
WebSocket-Key,服務端獲取到key,然後將這個key與字元串258EAFA5-E914-47DA-95CA-C5AB0DC85B11
相連,對新的字元串通過sha1安全散列演算法計算出結果後,再進行base64編碼,並且將結果放在請求頭的"Sec-WebSocket-
Accept"中返回即可完成握手。具體請看代碼:
server.on('upgrade', function (req, socket, upgradeHead) {
var key = req.headers['sec-websocket-key'];
key = crypto.createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");
var headers = [
'HTTP/1.1 101 Switching Protocols',
'Upgrade: websocket',
'Connection: Upgrade',
'Sec-WebSocket-Accept: ' + key
];
socket.setNoDelay(true);
socket.write(headers.join("\r\n") + "\r\n\r\n", 'ascii');
var ws = new WebSocket(socket);
webSocketCollector.push(ws);
callback(ws);
});
upgrade事件其實是http這個模塊的封裝,再往底層就是net模塊的實現,其實都差不多,如果直接用net模塊來實現的話,就是監聽net.createServer返回的server對象的data事件,接收到的第一份數據就是客戶端發來的升級請求報文。
上面那段代碼就完成了websocket的握手,然後就可以開始數據傳輸了。
看數據傳輸之前,先看看websocket數據幀的定義(因為覺得深入淺出nodejs里的幀定義圖最容易理解,所以就貼這張了):
上面的圖中,每一列就是一個位元組,一個位元組總共是8位,每一位就是一個二進制數,不同位的值會對應不同的意義。
fin:指示這個是消息的最後片段。第一個片段可能也是最後的片段。如果為1即為最後片段,(其實這個位的用途我個人有點疑惑,按照書上以及網上查的資
料,當數據被分片的時候,不同片應該都會有fin位,會根據fin為是不是0來判斷是否為最後一幀,但是實際實現中卻發現,當數據比較大需要分片時,服務
端收到的數據就只有第一幀是有fin位為1,其他幀則整個幀都是數據段,也就是說,感覺這個fin位似乎用不上,至少我自己寫的demo中是通過數據長度
來判斷是否到了最後一幀,完全沒用到這個fin位是否為1來判斷)
rsv1、rsv2、rsv3:各佔一個位,用於擴展協商,基本上不怎麼需要理,一般都是0
opcode:佔四個位,可以表示0~15的十進制,0表示為附加數據幀,1表示為文本數據幀,2表示二進制數據幀,8表示發送一個連接關閉的數據幀,9
表示ping,10表示pong,ping和pong都是用於心跳檢測,當一端發送ping時,另一端必須響應pong表示自己仍處於響應狀態。
masked:佔一個位,表示是否進行掩碼處理,客戶端發送給服務端時為1,服務端發送給客戶端時為0
payload
length:佔7位,或者7+16位、或者7+64位。如果第二個位元組的後面七個位的十進制值小於或等於125,則直接用這七個位表示數據長度;如果該
值為126,說明
125<數據長度<65535(16個位能描述的最大值,也就是16個1的時候),就用第三個位元組及第四個位元組即16個位來表示;如果該值為
127,則說明數據長度已經大於65535,16個位也已經不足以描述數據長度了,就用第三到第十個位元組這八個位元組來描述數據長度。
masking key:當masked為1的時候才存在,用於對我們需要的數據進行解密。
payload data:我們需要的數據,如果masked為1,該數據會被加密,要通過masking key進行異或運算解密才能獲取到真實數據。
幀定義解釋完了,就可以根據數據來進行解析了,當有data過來的時候,先獲取需要的數據信息,下面這段代碼將獲取到數據在data里的位置,以及數據長度,masking key以及opcode:
WebSocket.prototype.handleDataStat = function (data) {
if (!this.stat) {
var dataIndex = 2; //數據索引,因為第一個位元組和第二個位元組肯定不為數據,所以初始值為2
var secondByte = data[1]; //代表masked位和可能是payloadLength位的第二個位元組
var hasMask = secondByte >= 128; //如果大於或等於128,說明masked位為1
secondByte -= hasMask ? 128 : 0; //如果有掩碼,需要將掩碼那一位去掉
var dataLength, maskedData;
//如果為126,則後面16位長的數據為數據長度,如果為127,則後面64位長的數據為數據長度
if (secondByte == 126) {
dataIndex += 2;
dataLength = data.readUInt16BE(2);
} else if (secondByte == 127) {
dataIndex += 8;
dataLength = data.readUInt32BE(2) + data.readUInt32BE(6);
} else {
dataLength = secondByte;
}
//如果有掩碼,則獲取32位的二進制masking key,同時更新index
if (hasMask) {
maskedData = data.slice(dataIndex, dataIndex + 4);
dataIndex += 4;
}
//數據量最大為10kb
if (dataLength > 10240) {
this.send("Warning : data limit 10kb");
} else {
//計算到此處時,dataIndex為數據位的起始位置,dataLength為數據長度,maskedData為二進制的解密數據
this.stat = {
index: dataIndex,
totalLength: dataLength,
length: dataLength,
maskedData: maskedData,
opcode: parseInt(data[0].toString(16).split("")[1] , 16) //獲取第一個位元組的opcode位
};
}
} else {
this.stat.index = 0;
}
};
代碼中均有注釋,理解起來應該不難,直接看下一步,獲取到數據信息後,就要對數據進行實際解析了:
經過上面handleDataStat方法的處理,stat中已經有了data的相關數據,先判斷opcode,如果為9說明是客戶端發起的
ping心跳檢測,直接返回pong響應,如果為10則為服務端發起的心跳檢測。如果有masking
key,則遍歷數據段,對每個位元組都與masking
key的位元組進行異或運算(網上看到一個說法很形象:就是輪流發生X關系),^符號就是進行異或運算啦。如果沒有masking
key則直接通過slice方法把數據截取下來。
獲取到數據後,放進datas里保存,因為有可能數據被分片了,所以再將stat里的長度減去當前數據長度,只有當stat里的長度為0的時候,
說明當前幀為最後一幀,然後通過Buffer.concat將所有數據合並,此時再判斷一下opcode,如果opcode為8,則說明客戶端發起了一個
關閉請求,而我們獲取到的數據則是關閉原因。如果不為8,則這數據就是我們需要的數據。然後再將stat重置為null,datas數組置空即可。至此,
我們的數據解析就完成了。
WebSocket.prototype.dataHandle = function (data) {
this.handleDataStat(data);
var stat;
if (!(stat = this.stat)) return;
//如果opcode為9,則發送pong響應,如果opcode為10則置pingtimes為0
if (stat.opcode === 9 || stat.opcode === 10) {
(stat.opcode === 9) ? (this.sendPong()) : (this.pingTimes = 0);
this.reset();
return;
}
var result;
if (stat.maskedData) {
result = new Buffer(data.length-stat.index);
for (var i = stat.index, j = 0; i < data.length; i++, j++) {
//對每個位元組進行異或運算,masked是4個位元組,所以%4,藉此循環
result[j] = data[i] ^ stat.maskedData[j % 4];
}
} else {
result = data.slice(stat.index, data.length);
}
this.datas.push(result);
stat.length -= (data.length - stat.index);
//當長度為0,說明當前幀為最後幀
if (stat.length == 0) {
var buf = Buffer.concat(this.datas, stat.totalLength);
if (stat.opcode == 8) {
this.close(buf.toString());
} else {
this.emit("message", buf.toString());
}
this.reset();
}
};
完成了客戶端發來的數據解析,還需要一個服務端發數據至客戶端的方法,也就是按照上面所說的幀定義來組裝數據並且發送出去。下面的代碼中基本上每一行都有注釋,應該還是比較容易理解的。
//數據發送
WebSocket.prototype.send = function (message) {
if(this.state !== "OPEN") return;
message = String(message);
var length = Buffer.byteLength(message);
// 數據的起始位置,如果數據長度16位也無法描述,則用64位,即8位元組,如果16位能描述則用2位元組,否則用第二個位元組描述
var index = 2 + (length > 65535 ? 8 : (length > 125 ? 2 : 0));
// 定義buffer,長度為描述位元組長度 + message長度
var buffer = new Buffer(index + length);
// 第一個位元組,fin位為1,opcode為1
buffer[0] = 129;
// 因為是由服務端發至客戶端,所以無需masked掩碼
if (length > 65535) {
buffer[1] = 127;
// 長度超過65535的則由8個位元組表示,因為4個位元組能表達的長度為4294967295,已經完全夠用,因此直接將前面4個位元組置0
buffer.writeUInt32BE(0, 2);
buffer.writeUInt32BE(length, 6);
} else if (length > 125) {
buffer[1] = 126;
// 長度超過125的話就由2個位元組表示
buffer.writeUInt16BE(length, 2);
} else {
buffer[1] = length;
}
// 寫入正文
buffer.write(message, index);
this.socket.write(buffer);
};
最後還要實現一個功能,就是心跳檢測:防止服務端長時間不與客戶端交互而導致客戶端關閉連接,所以每隔十秒都會發送一次ping進行心跳檢測
//每隔10秒進行一次心跳檢測,若連續發出三次心跳卻沒收到響應則關閉socket
WebSocket.prototype.checkHeartBeat = function () {
var that = this;
setTimeout(function () {
if (that.state !== "OPEN") return;
if (that.pingTimes >= 3) {
that.close("time out");
return;
}
//記錄心跳次數
that.pingTimes++;
that.sendPing();
that.checkHeartBeat();
}, 10000);
};
WebSocket.prototype.sendPing = function () {
this.socket.write(new Buffer(['0x89', '0x0']))
};
WebSocket.prototype.sendPong = function () {
this.socket.write(new Buffer(['0x8A', '0x0']))
};
至此,整個websocket的實現就完成了,此demo只是大概實現了一下websocket而已,在安全之類方面肯定還是有很多問題,若是真正生產環境中還是用socket.io這類成熟的插件比較好。不過這還是很值得一學的。
『陸』 如何解析nodejs中send方法發送的數據
參考如下實例代碼:self.sendAliMessage=function(req,res){varparam={'Action':'SingleSendSms','SignName':'xxxx',//簡訊簽名名稱'TemplateCode':'SMS_1635xxxx','RecNum':'13564096???',//手機號'ParamString':JSON.stringify({"code":"9527"}),//驗證碼模板里的變數'Version':'2016-09-27','Format':'JSON','AccessKeyId':ali_access_key_id,'SignatureMethod':'HMAC-SHA1','SignatureVersion':'1.0','SignatureNonce':randomstr(9),//隨機數'Timestamp':newDate().toISOString(),};param.Signature=sign.signForAliMessage(param,ali_access_key_secret);varapi_url='/';request.post({url:api_url,headers:{'Content-Type':'application/x-www-form-urlencoded'},form:param},function(err,response,data){varresultdata=JSON.parse(data);if(!err&&data.Model){result=res.returnData(200);}else{result=res.returnData(113);}res.send(result);});}/*簽名方法*/sign.signForAliMessage=function(src_sign,access_key_secret){varparam,qstring=[];varoa=Object.keys(src_sign).sort(),on={};for(vari=0;i
『柒』 如何使用Node.js處理前端代碼文件的編碼問題
使用 NodeJS 編寫前端工具時,操作得最多的是文本文件,因此也就涉及到了文件編碼的處理問題。我們常用的文本編碼有 UTF8 和 GBK 兩種,並且 UTF8 文件還可能帶有 BOM。在讀取不同編碼的文本文件時,需要將文件內容轉換為 JS 使用的 UTF8 編碼字元串後才能正常處理。
1、BOM 的移除
BOM 用於標記一個文本文件使用 Unicode 編碼,其本身是一個 Unicode 字元("uFEFF"),位於文本文件頭部。在不同的 Unicode 編碼下,BOM 字元對應的二進制位元組如下:
3、單位元組編碼
有時候,我們無法預知需要讀取的文件採用哪種編碼,因此也就無法指定正確的編碼。比如我們要處理的某些 CSS 文件中,有的用 GBK 編碼,有的用 UTF8 編碼。雖然可以一定程度可以根據文件的位元組內容猜測出文本編碼,但這里要介紹的是有些局限,但是要簡單得多的一種技術。
首先我們知道,如果一個文本文件只包含英文字元,比如 Hello World,那無論用 GBK 編碼或是 UTF8 編碼讀取這個文件都是沒問題的。這是因為在這些編碼下,ASCII0~128 范圍內字元都使用相同的單位元組編碼。
反過來講,即使一個文本文件中有中文等字元,如果我們需要處理的字元僅在 ASCII0~128 范圍內,比如除了注釋和字元串以外的JS代碼,我們就可以統一使用單位元組編碼來讀取文件,不用關心文件的實際編碼是 GBK 還是 UTF8。
『捌』 nodejs 給appium日誌添加註釋
說實話,我覺得你這種需求的正確實現方法應該是直接改一下appium的代碼,在需要的地方插入自己的注釋就行,和直接操作字元串相比這樣更靈活。appium的源碼就在安裝目錄的node_molesappium下,根據日誌的關鍵字搜索一下,定位到需要的位置即可,例如這一段:
=============Set Port============
[Appium] Appium REST http interface listener started on127.0.0.1:4723
根據「 Appium REST http interface listener started on 」為關鍵字搜一下,可以定位到如下位置
下面的就不用說了吧,這么做的好處是可以按需添加註釋,順便還可以了解一下appium的代碼結構,缺點可能就是appium如果升級,會把改的注釋蓋掉,改完注意備份就好
『玖』 nodejs-koa2(mvc模式)前後端分離 前端設計
前後端分離,前端nodejs運行環境,使用koa2集成負責資源分配與用戶交互,實現token驗證用戶身份,路由控制。等!
自行 網路 解決;
"program": "${workspaceFolder}app.js"
此處就是是將app.js作為啟動文件。${workspaceFolder}代表根目錄,vsc啟動時會在根目錄下找到並載入app.js文件。
參數介紹: name 項目名稱、 version 版本號、 description 項目描述、 main 項目啟動文件、 scripts 啟動快捷設置, author 作者, dependencies 第3方中間件名稱及版本。
最重要的
「 dependencies 」這里添加一些要用到的包,以上是這次要用到的所有的包,版本自己更改。
「 scripts 」這里是一些nodejs的便捷命令,上線的時候會用到,直接在終端中,package.json同級目錄 ,執行『npm start』 即 可啟動app.js。
別的沒啥太大作用瞎寫即可。
啟動相關配置,封裝到config/init.js中,啟動文件直接引用即可
3-6-1、init.js項目核心。
異常友好處理方法封裝
路由配置
視圖渲染
核心集成
3-6-2、config.js項目參數配置。為什麼不用json文件 因為json不能加註釋
3-6-3、token.js項目token相關方法封裝。
執行後項目結構會增加兩個文件
新增
src/hello.js。
views/index.html
瀏覽器訪問: http://127.0.0.1:3000/koa/login
輸入值獲取token
獲取的token如圖:
先不用帶token進行訪問: http://127.0.0.1:3000/koa/ hello/jiaobaba,被token攔截,返回401
帶上token訪問: http://127.0.0.1:3000/koa/ hello/jiaobaba
測試頁面渲染,及跳轉html頁面,直接訪問 http://127.0.0.1:3000/koa /views
結束!!!!!!
需要源碼聯系我
『拾』 nodejs+express+ejs生成項目
一、說一下
首先保證node環境已經安裝完畢,npm能正常使用,安裝可自行網路,比較簡單,在此不做贅述。
node是否安裝成功
express是否安裝成功
二、直接開碼
安裝
注釋:
express:安裝express框架
express-generator:安裝express生成器,可快速生成一個應用的骨架
裂李-g:全局安答洞裝
注釋:
-e:簡寫,全稱為 --view=ejs ,安裝ejs模板引擎
myapp:項目名稱,自定義即可
生成如下目錄結構
注釋:
bin:存放啟動腳本文件
bin/www:啟動腳本文件,可修改埠號,等功能。
public:存放肆舉遲圖片,css,js等靜態文件
routes:存放路由模塊文件
views:存放視圖文件,使用的ejs模板引擎
app.js:入口文件,重要的配置文件
package.json:工程信息和安裝依賴文件
跟著提示執行下列語句
注釋:
cd myapp:進入myapp文件夾,文件名需修改成自己的項目文件名
npm install:安裝所有依賴模塊,常用的非指定性npm安裝命令
npm start:運行項目
(bin/www)