一、全局變量
在 Node 中常用的全局方法有 CommonJS、Buffer、process、console、timer 等,這些方法不需要 require
引入 API 就可以直接使用。
如果希望有屬性或方法可以“全局使用”,那就將它掛載在 Node 的global
對象上:
global.gNum = 300
console.log(gNum); // 300
在 Node 中所有模塊都可以使用這些全局變量,以下就介紹 Node 中的全局變量
二、 CommonJS 模塊
Node CommonJS 模塊規範根據實現了module
、exports
和require
模塊機制。Node 對每個文件都被進行了模塊封裝,每個模塊有自己的作用域,如在 debug 時看到的:
(function (exports, require, module, __filename, __dirname) {
// some code
});
模塊機制中的 __dirname
、__filename
、exports
、module
、require()
這些變量雖然看起來是全局的,但其實它們僅存在於模塊範圍。需要注意的幾點是:
- 模塊內部
module
變量代表模塊本身 - 模塊提供
require()
方法引入外部模塊到當前的上下文中 -
module.exports
屬性代表模塊對外接口,默認的快捷方式exports
簡單的使用方式如下:
/* common_exports.js */
exports.num = 100
exports.obj = {
a : 200
}
exports = {
count : 300
}
/* common_require.js */
const mod = require('./common_exports')
console.log(mod) // { num: 100, obj: { a: 200 } }
console.log(mod.count) // undefined
注意到上例中的mod.count
爲undefined
,這是因爲exports
只是module.exports
的引用,可以給exports
添加屬性,但不能修改exports
的指向。
更深入的瞭解模塊機制可以看 【Node】前後端模塊規範與模塊加載原理
三、process 進程對象
process 包含了進程相關的屬性和方法,Node 的 process 文檔 中的內容特別多,列舉幾個常用
3.1 argv 啓動參數
Node 進程啓動時傳遞的參數都在 process.arg
數組中:
// process.js
const {argv , execPath} = process
argv.forEach((val, index) => {
console.log(`${index}: ${val}`)
})
console.log(execPath)
可以在執行 process.js 時傳遞其他參數,這些參數都會保存在 argv
中:
$ node apiTest/process.js one=1 --inspect --version
0: /usr/local/bin/node
1: /Users/mobike/Documents/webProjects/testNode/apiTest/process.js
2: one=1
3: --inspect
4: --version
/usr/local/bin/node
process.argv
第一個參數就是 process.execPath
,即調用執行程序 Node 的路徑,第二個參數時被執行的 JS 文件路徑,剩下的就是自定義參數。
3.2 env 環境對象
process.env
是包含運行環境各種參數的對象,可以直接輸出env
查看所有參數信息,也可以輸出某個屬性:
const {env} = process.env
console.log(env.PATH) // /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/Documents/webProjects/testNode/node_modules/.bin
console.log(env.SHELL) // /bin/zsh
在 webpack 打包過程中常用process.env.NODE_ENV
判斷生產環境或開發環境,process.env
是沒有NODE_ENV
這個屬性的,你可以在系統環境變量中配置,也可以在項目程序直接設置process.env.NODE_ENV=‘dev’
。
3.3 cwd 當前目錄
process.cwd()
方法返回 Node.js 進程的當前工作目錄,和 Linus 命令$ pwd
功能一樣:
// process.js
console.log(process.cwd()) // /Users/Documents/webProjects/testNode
$ node process.js
/Users/WebstormProjects/testNode
$ pwd
/Users/WebstormProjects/testNode
四、Timers 異步
Node 中的計時器方法與 Web 瀏覽器中的JS 計時器類似,但內部實現是基於 Node 的 Event Loop。Node 中的計時器有setImmediate()
、setTimeout()
、setInterval()
。
在 Node 中有一個輕量級的process.nextTick()
異步方法,它是在當前事件隊列結束時調用,setImmediate()
是當前 Node Event Loop 結束時立即執行,那執行順序有什麼區別呢?
下面舉例說明process.nextTick(fn)
與setImmediate(fn)
與setTimeout(fn,0)
之間的區別:
// timer.js
setImmediate(()=>{
console.log("setImmediate")
});
setTimeout(()=>{
console.log("setTimeout 0")
},0);
setTimeout(()=>{
console.log("setTimeout 100")
},100);
process.nextTick(()=>{
console.log("nextTick")
process.nextTick(()=>{
console.log("nextTick inner")
})
});
看下執行結果:
$ node timer.js
nextTick
nextTick inner
setTimeout 0
setImmediate
setTimeout 100
process.nextTick()
中的回調函數最快執行,因爲它將異步事件插入到當前執行隊列的末尾,但如果process.nextTick()
中的事件執行時間過長,後面的異步事件就被延遲。
setImmediate()
執行最慢,因爲它將事件插入到下一個事件隊列的隊首,不會影響當前事件隊列的執行。當setTimeout(fn, 0)
是在setImmediate()
之前執行。
以上就是 Node 全局變量的概述,其他的 API 或內置模塊都需要·require('xxx')
引入使用,我們可以在 nodejs.cn 中查看關於 Global API 更詳細的介紹。
五、Debug 調試方法
Node 的調試方法有很多,主要分爲安裝 node-inspect 包調試、用 Chrome DevTools 調試和 IDE 調試,可以在官網的 Docs Debugging Guide 查看安裝方法。
下面介紹使用 Chrome DevTools 調試的方法,首先安裝 Chrome Extension NIM,打開 Inspect 入口頁面 chrome://inspect
寫一個簡單 debug.js 測試文件:
// apiTest/debug.js
console.log("this is debug test")
function test () {
console.log("hello world")
}
test()
使用node --inspect-brk
來啓動腳本,-brk
相當於在程序入口前加一個斷點,使得程序會在執行前停下來
$ node --inspect-brk apiTest/debug.js
Debugger listening on ws://127.0.0.1:9229/44b5d11e-3261-4090-a18c-2d811486fd0a
For help, see: https://nodejs.org/en/docs/inspector
在 chrome://inspect 中設置監聽端口 9229(默認),就可以看到可以 debug 的頁面:
(function (exports, require, module, __filename, __dirname) {
console.log("this is debug test")
function test () {
console.log("hello world")
}
test()
});
如果我們使用node --inspect
來啓動腳本,那整個代碼直接運行到代碼結尾,無法進行調試,但此時 Node 還進程沒有結束,所以可以在 http://127.0.0.1:9229/json/list 查詢 devtoolsFrontendUrl ,複製此 Url 到 Chrome 上進行調試。
看到使用 Chrome DevTools 的調試方法還是比較複雜的,一些 IDE 都支持直接斷點調試,推薦WebStorm、VScode。
接下來會整理學習 Node 的基礎 API、項目構建、網絡編程、異步編程等知識點,加油呢少年~