【Node】常用的全局變量與 Inspect 調試

一、全局變量

在 Node 中常用的全局方法有 CommonJS、Buffer、process、console、timer 等,這些方法不需要 require引入 API 就可以直接使用。

如果希望有屬性或方法可以“全局使用”,那就將它掛載在 Node 的global對象上:

global.gNum = 300
console.log(gNum); // 300

在 Node 中所有模塊都可以使用這些全局變量,以下就介紹 Node 中的全局變量

二、 CommonJS 模塊

Node CommonJS 模塊規範根據實現了moduleexportsrequire模塊機制。Node 對每個文件都被進行了模塊封裝,每個模塊有自己的作用域,如在 debug 時看到的:

(function (exports, require, module, __filename, __dirname) { 
    // some code
});

模塊機制中的 __dirname__filenameexportsmodulerequire()這些變量雖然看起來是全局的,但其實它們僅存在於模塊範圍。需要注意的幾點是:

  • 模塊內部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.countundefined,這是因爲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、項目構建、網絡編程、異步編程等知識點,加油呢少年~

圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章