自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

探索 Node.js v20 功能的實(shí)際應(yīng)用

開(kāi)發(fā) 前端
在這篇文章中,我們探討了 Node.js v20 ?中引入的一些功能。首先,我們研究了如何使用實(shí)驗(yàn)性權(quán)限模型。然后,我們了解了如何使用現(xiàn)在穩(wěn)定的內(nèi)置測(cè)試運(yùn)行程序。從那里,我們了解了 V8 JavaScript 引擎中可用的新功能。
原文作者:Stanley Ulili

原文地址:https://blog.logrocket.com/exploring-node-js-v20-features/

翻譯:一川

1寫(xiě)在前面

Node.js的每個(gè)版本都帶有令人興奮的新功能,v20也不例外。Node.js v20 于 2023 年 4 月 18 日發(fā)布。此版本附帶了更新的功能,旨在通過(guò)使用穩(wěn)定的內(nèi)置測(cè)試運(yùn)行程序減少依賴(lài)性,使 Node.js 比以往任何時(shí)候都更安全。Node.js v20還提供了創(chuàng)建單個(gè)可執(zhí)行應(yīng)用程序的功能,這些應(yīng)用程序可以在Windows,macOS和Linux上執(zhí)行,而無(wú)需在其系統(tǒng)上安裝Node.js。

在本教程中,我們將探討 Node.js v20 中提供的一些功能。您需要在計(jì)算機(jī)上安裝 Node.js v20 或更高版本,并熟悉創(chuàng)建和運(yùn)行 Node.js 程序才能遵循。

2實(shí)驗(yàn)性權(quán)限模型

Node.js v20 中引入的主要功能之一是實(shí)驗(yàn)性的權(quán)限模型,旨在使 Node.js 更安全。長(zhǎng)期以來(lái),Node.js沒(méi)有權(quán)限系統(tǒng)。任何應(yīng)用程序都可以與文件系統(tǒng)交互,甚至可以在用戶(hù)計(jì)算機(jī)上生成進(jìn)程。

這為攻擊打開(kāi)了大門(mén),第三方軟件包在未經(jīng)用戶(hù)同意的情況下訪問(wèn)了用戶(hù)的計(jì)算機(jī)資源。為了降低風(fēng)險(xiǎn),權(quán)限模型限制Node.js應(yīng)用程序訪問(wèn)文件系統(tǒng)、創(chuàng)建工作線程和生成子進(jìn)程。

啟用權(quán)限模型后,用戶(hù)可以運(yùn)行應(yīng)用程序,而不必?fù)?dān)心惡意第三方包可以訪問(wèn)機(jī)密文件、刪除或加密文件,甚至運(yùn)行有害程序。權(quán)限模型還允許用戶(hù)在運(yùn)行應(yīng)用程序或運(yùn)行時(shí)向 Node.js 應(yīng)用授予特定權(quán)限。

實(shí)現(xiàn)權(quán)限模型

讓我們看看如何使用權(quán)限模型。使用您選擇的名稱(chēng)創(chuàng)建一個(gè)目錄:

mkdir example_app

創(chuàng)建一個(gè) package.json 文件:

npm init -y

添加到 type:module 支持 ESM 模塊:

{
  ...
  "type": "module"
}

然后,創(chuàng)建包含以下內(nèi)容的: data.txt

Text content that will be read in a Node.js program.

接下來(lái),創(chuàng)建一個(gè) index.js 文件并添加以下代碼來(lái)讀取 data.txt 該文件:

import { readFile } from "fs/promises";

async function readFileContents(filename) {
  const content = await readFile(filename, "utf8"); // <!-
  console.log(content);
}

readFileContents("./data.txt");

在這里,定義一個(gè)readFileContents函數(shù),該函數(shù)接受 并從 filename 文件系統(tǒng)讀取文件。在函數(shù)中,調(diào)用readFile() fs模塊的方法讀取data.txt文件內(nèi)容,然后將它們記錄在控制臺(tái)中。

現(xiàn)在,使用 node 以下命令運(yùn)行文件:

node index.js

我們將在控制臺(tái)中看到如下所示的輸出:

Text content that will be read in a Node.js program.

若要啟用實(shí)驗(yàn)性權(quán)限模型,請(qǐng)使用以下--experimental-permission標(biāo)志運(yùn)行文件:

node --experimental-permission index.js

這次我們收到如下所示的錯(cuò)誤:

// output
node:internal/modules/cjs/loader:179
  const result = internalModuleStat(filename);
                 ^

Error: Access to this API has been restricted
    at stat (node:internal/modules/cjs/loader:179:18)
    at Module._findPath (node:internal/modules/cjs/loader:651:16)
    at resolveMainPath (node:internal/modules/run_main:15:25)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:24)
    at node:internal/main/run_main_module:23:47 {
  code: 'ERR_ACCESS_DENIED',
  permission: 'FileSystemRead',
  resource: '/home/<your_username>/example_app/index.js'
}

錯(cuò)誤消息讓我們知道我們沒(méi)有讀取文件的權(quán)限。權(quán)限模型限制了文件系統(tǒng)訪問(wèn)。如果嘗試生成工作線程和子進(jìn)程,也會(huì)收到一條錯(cuò)誤消息。

要授予對(duì)文件或目錄的讀/寫(xiě)訪問(wèn)權(quán)限,可以使用該 --allow-fs-read 標(biāo)志。以下是可以使用的一些選項(xiàng):

  • --allow-fs-read=* :通配符 * 提供對(duì)文件系統(tǒng)上所有目錄/文件的讀取訪問(wèn)權(quán)限
  • --allow-fs-read=/home/<username>/ :指定 /home/<username> 目錄應(yīng)具有讀取訪問(wèn)權(quán)限
  • --allow-fs-read=/tmp/filename.txt :這只允許對(duì)給定文件名的讀取訪問(wèn),即 filename.txt

還可以使用標(biāo)志 --allow-fs-write 授予寫(xiě)入訪問(wèn)權(quán)限。它還接受通配符、目錄路徑或文件名,如上所述。如前所述,權(quán)限模型還阻止 Node.js 程序創(chuàng)建子進(jìn)程。要授予權(quán)限,我們需要傳遞: --allow-child-process

node --experimental-permission --allow-child-process index.js

為了允許創(chuàng)建工作線程來(lái)并行執(zhí)行任務(wù),可以改用該 --allow-worker 標(biāo)志:

node --experimental-permission --allow-worker index.js

因此,回到前面的示例,授予Node.js讀取data.txt.執(zhí)行此操作的更靈活的方法是提供 駐data.txt留的完整目錄路徑,如下所示:

node --experimental-permission --allow-fs-read=/home/<your_username>/example_app index.js

現(xiàn)在,程序可以毫無(wú)問(wèn)題地讀取文件,盡管它提供了警告:

(node:8506) ExperimentalWarning: Permission is an experimental feature
(Use `node --trace-warnings ...` to show where the warning was created)
Text content that will be read in a Node.js program.

啟用權(quán)限模型后,可能不知道應(yīng)用程序是否具有寫(xiě)入或讀取文件系統(tǒng)的權(quán)限。為了防止運(yùn)行時(shí) ERR_ACCESS_DENIED 錯(cuò)誤,權(quán)限模型允許在運(yùn)行時(shí)檢查權(quán)限。

要檢查是否具有讀取權(quán)限,可以執(zhí)行以下操作:

if(process.permission.has('fs.read')) {
  // proceed to read the file
}

或者,可以檢查目錄的權(quán)限。在下面的代碼中,檢查是否對(duì)給定目錄具有寫(xiě)入權(quán)限:

if (process.permission.has('fs.write', '/home/username/') ) {
  //do your thing
}

有了這個(gè),我們現(xiàn)在就可以創(chuàng)建安全的應(yīng)用程序并保護(hù)我們機(jī)器的資源在未經(jīng)我們同意的情況下不被訪問(wèn)。若要探索權(quán)限模型中的更多功能,請(qǐng)?jiān)L問(wèn)文檔。

3穩(wěn)定的測(cè)試運(yùn)行器

在Node.js v18發(fā)布之前,Node.js 中的所有測(cè)試運(yùn)行器都是第三方軟件包,例如 Jest 和 Mocha。雖然它們?yōu)?nbsp;Node.js 社區(qū)提供了良好的服務(wù),但第三方庫(kù)可能是不可預(yù)測(cè)的。

首先,Jest有一個(gè)錯(cuò)誤,它會(huì)破壞 instanceof 控制器,產(chǎn)生誤報(bào)。解決方案是安裝另一個(gè)第三方軟件包。內(nèi)置工具傾向于按預(yù)期工作并且更加標(biāo)準(zhǔn)化,如 Python 或 Go,它們都附帶內(nèi)置測(cè)試運(yùn)行器。

甚至像Deno和 Bun 這樣的更新的 JavaScript 運(yùn)行時(shí)也帶有測(cè)試運(yùn)行器。Node.js 一直被拋在后面,直到Node.js v18發(fā)布,它附帶了一個(gè)實(shí)驗(yàn)性測(cè)試運(yùn)行器?,F(xiàn)在,隨著 Node.js v20 版本的發(fā)布,測(cè)試運(yùn)行程序是穩(wěn)定的,可以在生產(chǎn)中使用。以下是測(cè)試運(yùn)行程序中提供的一些功能:

  • mocking
  • skipping tests 跳過(guò)測(cè)試
  • filtering tests 過(guò)濾測(cè)試
  • test coverage collection 測(cè)試覆蓋率收集
  • 監(jiān)視模式(實(shí)驗(yàn)性),在檢測(cè)到更改時(shí)自動(dòng)運(yùn)行測(cè)試

使用測(cè)試運(yùn)行程序

讓我們?cè)敿?xì)探討測(cè)試運(yùn)行程序。首先, calculator.js 使用以下代碼創(chuàng)建一個(gè):

// calculator.js
export function add(x, y) {
  return x + y;
}

export function divide(x, y) {
  return x / y;
}

之后,創(chuàng)建一個(gè) test 目錄中的文件目錄 calculator_test.js 。在文件中,添加以下代碼以使用內(nèi)置測(cè)試運(yùn)行程序測(cè)試函數(shù):

// calculator_test.js
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { add, divide } from "../calculator.js";

describe("Calculator", () => {

  it("can add two numbers", () => {
    const result = add(2, 5);
    assert.strictEqual(result, 7);
  });

  it("can divide two numbers", () => {
    const result = divide(15, 5);
    assert.strictEqual(result, 3);
  });
});

在上面的代碼中,我們從 導(dǎo)入 describe node:test / it 關(guān)鍵字,如果您使用過(guò) Jest,應(yīng)該很熟悉。我們也 assert 從 . node:assert/strict 然后,我們測(cè)試 divide() 和 add() 函數(shù)是否按預(yù)期工作。按如下方式運(yùn)行測(cè)試:

node --test

運(yùn)行測(cè)試將生成與以下內(nèi)容匹配的輸出:

? Calculator
  ? can add two numbers (0.984478ms)
  ? can divide two numbers (0.291951ms)
? Calculator (5.135785ms)

? tests 2
? suites 1
? pass 2
? fail 0
? cancelled 0
? skipped 0
? todo 0
? duration_ms 158.853226

當(dāng)我們運(yùn)行測(cè)試時(shí),內(nèi)置運(yùn)行器會(huì)搜索所有后綴為 .js 、 .cjs 的JavaScript測(cè)試文件,前提是 .mjs :

  • 它們駐留在名為 test
  • 文件名以 test-
  • 文件名以 、 -test 或_test結(jié)尾 _test

我們還可以在運(yùn)行時(shí) node --test 提供包含測(cè)試的目錄。如果我們想跳過(guò)一些測(cè)試,我們需要提供該 skip: true 選項(xiàng)作為 it 塊的第二個(gè)參數(shù):

...
describe("Calculator", () => {
  it("can add two numbers", () => {
    const result = add(2, 5);
    assert.strictEqual(result, 7);
  });
  // skip test
  it("can divide two numbers", { skip: true }, () => {
    const result = divide(15, 5);
    assert.strictEqual(result, 3);
  });
 }
)

當(dāng)重新運(yùn)行測(cè)試時(shí),將看到只有一個(gè)測(cè)試運(yùn)行:

? Calculator
  ? can add two numbers (0.954955ms)
  ﹣ can divide two numbers (0.214886ms) # SKIP
? Calculator (5.111238ms)
...

Node.js v20 還附帶了一個(gè)實(shí)驗(yàn)性監(jiān)視模式,一旦檢測(cè)到測(cè)試文件中的更改,它就可以自動(dòng)運(yùn)行測(cè)試。我們需要傳遞 --watch 標(biāo)志并提供目錄以在監(jiān)視模式下運(yùn)行測(cè)試:

node --test --watch  test/*.js

如果更改文件,Node.js 將自動(dòng)選取更改并重新運(yùn)行測(cè)試。

只是觸及了測(cè)試運(yùn)行程序可以做什么的表面。查看文檔以繼續(xù)探索它。

4V8 JavaScript 引擎更新到 v11.3

Node.js建立在高性能的V8 JavaScript引擎之上,該引擎也為Google Chrome提供支持。它實(shí)現(xiàn)了更新的 ECMAScript 特性。當(dāng)新版本的 Node.js 發(fā)布時(shí),它附帶了最新版本的 V8 JavaScript 引擎。最新版本是V8 v11.3,它具有一些顯著的功能,包括:

  • 可 ArrayBuffer 調(diào)整大?。焊鶕?jù)給定的大小(以字節(jié)為單位)調(diào)整大小 ArrayBuffer
  • 可 SharedArrayBuffer 增長(zhǎng): ShareArrayBuffer 根據(jù)給定的大?。ㄒ宰止?jié)為單位)增長(zhǎng)
  • String.prototype.isWellFormed() :如果字符串格式正確且不包含單獨(dú)的代理項(xiàng),則返回 true
  • String.prototype.toWellFormed() :修復(fù)并返回沒(méi)有單獨(dú)代理項(xiàng)問(wèn)題的字符串
  • 正則表達(dá)式 -v 標(biāo)志:改進(jìn)了不區(qū)分大小寫(xiě)的匹配

讓我們探索用于調(diào)整 ArrayBuffer、SharedArrayBuffer 最令人興奮的新功能之一是調(diào)整 ArrayBuffer 。在 Node.js v20 之前,在創(chuàng)建緩沖區(qū)后調(diào)整緩沖區(qū)大小以容納更多數(shù)據(jù)是不可能的。使用 Node.js 20,我們可以使用該resize()方法調(diào)整它的大小,如以下示例所示:

//resize_buffer.js
const buffer = new ArrayBuffer(4, { maxByteLength: 10 });

if (buffer.resizable) {
  console.log("The Buffer can be resized!");
  buffer.resize(8); // resize the buffer
}
console.log(`New Buffer Size: ${buffer.byteLength}`);

首先,創(chuàng)建一個(gè)大小為字節(jié)的緩沖區(qū),其緩沖區(qū)限制為 10 使用該 maxByteLength 屬性指定的 4 字節(jié)數(shù)。有了緩沖區(qū)限制,如果我們要將其大小調(diào)整為超過(guò) 10 字節(jié),它將失敗。如果需要更多字節(jié),可以將 修改 maxByteLength 為所需的值。

接下來(lái),我們檢查緩沖區(qū)是否可調(diào)整大小,然后調(diào)用該方法 resize() 將緩沖區(qū)的大小從字節(jié)調(diào)整 4 為 8 字節(jié)。最后,我們記錄緩沖區(qū)大小。像這樣運(yùn)行文件:

node resize_buffer.js

下面是輸出:

The Buffer can be resized!
New Buffer Size: 8

緩沖區(qū)的大小已成功從字節(jié)調(diào)整 4 為 8 字節(jié)。也有 SharedArrayBuffer 相同的限制 ArrayBuffers ,但現(xiàn)在我們可以使用以下 grow() 方法將其增長(zhǎng)到我們選擇的大?。?/p>

// grow_buffer.js
const buffer = new SharedArrayBuffer(4, { maxByteLength: 10 });

if (buffer.growable) {
  console.log("The SharedArrayBuffer can grow!");
  buffer.grow(8);
}
console.log(`New Buffer Size: ${buffer.byteLength}`);

輸出如下所示:

The SharedArrayBuffer can grow!
New Buffer Size: 8

在示例中,我們檢查 是否 buffer 可增長(zhǎng)。如果它的計(jì)算結(jié)果為 true,我們調(diào)用該方法 grow() 以增加 SharedArrayBuffer 8 字節(jié)數(shù)。與 ArrayBuffer類(lèi)似,我們不應(yīng)該將其增長(zhǎng)到 maxByteLength。

5遞歸讀取目錄

目錄通常被認(rèn)為是樹(shù)結(jié)構(gòu),因?yàn)樗鼈儼幽夸?,子目錄也包含子目錄。從歷史上看, fs 該模塊readdir()的方法僅限于列出給定目錄的文件內(nèi)容,并且不會(huì)遞歸地遍歷子目錄并列出其內(nèi)容。因此,開(kāi)發(fā)人員轉(zhuǎn)向第三方庫(kù),如readdirp,recursive-readdir,klaw和fs-readdir-recursive。

Node.js v20 為 和 方法添加了一個(gè)recursive選項(xiàng),允許 readdirSync 方法遞歸讀取給定目錄和 readdir 子目錄。

假設(shè)有一個(gè)類(lèi)似于以下內(nèi)容的目錄結(jié)構(gòu):

├── dir1
│   ├── dir2
│   │   └── file4.txt
│   └── file3.txt
├── file1.txt
└── file2.txt

可以添加 recursive: true 列出所有文件的選項(xiàng),包括子目錄中的文件,如下所示:

// list_directories.js
import { readdir } from "node:fs/promises";

async function readFiles(dirname) {
  const entries = await readdir(dirname, { recursive: true });
  console.log(entries);
}
readFiles("data"); // <- "data" is the root directory name

運(yùn)行文件后,輸出將匹配以下內(nèi)容:

[
  'dir1',
  'file1.txt',
  'file2.txt',
  'dir1/dir2',
  'dir1/file3.txt',
  'dir1/dir2/file4.txt'
]

如果不將選項(xiàng)傳遞給 readdir() 該方法,輸出將 recursive 如下所示:

[ 'dir1', 'file1.txt', 'file2.txt' ]

雖然這是一個(gè)次要的補(bǔ)充,但它可以幫助我們減少項(xiàng)目中的依賴(lài)關(guān)系。

6單個(gè)可執(zhí)行實(shí)驗(yàn)性應(yīng)用程序

我們將在本文中探討的最后一個(gè)功能是Node.js v20中引入的實(shí)驗(yàn)性單可執(zhí)行應(yīng)用程序 (SEA)。它允許我們將應(yīng)用程序捆綁到Windows上的單個(gè)可執(zhí)行文件.exe或可以在macOS / Linux上運(yùn)行的二進(jìn)制文件中,而無(wú)需用戶(hù)在其系統(tǒng)上安裝Node.js。在撰寫(xiě)本文時(shí),它僅支持使用commons模塊系統(tǒng)的腳本。

讓我們創(chuàng)建一個(gè)二進(jìn)制文件。本節(jié)中的說(shuō)明僅適用于 Linux。在macOS和Windows上,某些步驟會(huì)有所不同,因此最好查閱文檔。首先,創(chuàng)建一個(gè)不同的目錄來(lái)包含代碼并移動(dòng)到其中:

mkdir sea_demo && cd sea_demo

在此之后,創(chuàng)建一個(gè) list_items.js 包含以下內(nèi)容的文件:

const items = ["cameras", "chargers", "phones"];
console.log("The following are the items:");
for (const item of items) {
  console.log(item);
}

接下來(lái),創(chuàng)建一個(gè)配置文件 sea-config.json ,用于創(chuàng)建可注入可執(zhí)行文件的 Blob:

{ "main": "list_items.js", "output": "sea-prep.blob" }

生成 Blob,如下所示:

node --experimental-sea-config sea-config.json
// Output:
Wrote single executable preparation blob to sea-prep.blob

復(fù)制可執(zhí)行文件并為其指定一個(gè)適合您的名稱(chēng):

cp $(command -v node) list_items

將 Blob 注入二進(jìn)制文件:

npx postject list_items NODE_SEA_BLOB sea-prep.blob \
    --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2

像這樣在系統(tǒng)上運(yùn)行二進(jìn)制文件:

The following are the items:
cameras
chargers
phones
(node:41515) ExperimentalWarning: Single executable application is an experimental feature and might change at any time
(Use `list_items --trace-warnings ...` to show where the warning was created)

這負(fù)責(zé)創(chuàng)建 SEA。如果您想了解如何為 macOS 或 Windows 創(chuàng)建二進(jìn)制文件,請(qǐng)查看文檔[https://nodejs.org/api/single-executable-applications.html]。

7寫(xiě)在最后

在這篇文章中,我們探討了 Node.js v20 中引入的一些功能。首先,我們研究了如何使用實(shí)驗(yàn)性權(quán)限模型。然后,我們了解了如何使用現(xiàn)在穩(wěn)定的內(nèi)置測(cè)試運(yùn)行程序。從那里,我們了解了 V8 JavaScript 引擎中可用的新功能。

之后,我們探索了如何遞歸讀取目錄,最后,我們使用實(shí)驗(yàn)性的單一可執(zhí)行應(yīng)用程序(SEA)功能創(chuàng)建了一個(gè)二進(jìn)制文件,該功能允許用戶(hù)在不安裝Node.js的情況下運(yùn)行Node.js程序。

責(zé)任編輯:武曉燕 來(lái)源: 宇宙一碼平川
相關(guān)推薦

2021-12-01 00:05:03

Js應(yīng)用Ebpf

2021-04-06 10:15:29

Node.jsHooks前端

2025-01-13 00:00:00

2021-12-25 22:29:57

Node.js 微任務(wù)處理事件循環(huán)

2021-10-26 06:43:36

NodeJavaScript引擎

2023-04-19 08:31:57

Node.jsLTS版本

2020-12-08 06:28:47

Node.js異步迭代器

2013-11-01 09:34:56

Node.js技術(shù)

2015-03-10 10:59:18

Node.js開(kāi)發(fā)指南基礎(chǔ)介紹

2011-11-10 11:08:34

Node.js

2020-05-29 15:33:28

Node.js框架JavaScript

2012-02-03 09:25:39

Node.js

2024-11-18 08:58:26

2020-07-31 13:35:34

Node.js應(yīng)用分析前端

2011-09-09 14:23:13

Node.js

2011-11-01 10:30:36

Node.js

2011-09-08 13:46:14

node.js

2011-09-02 14:47:48

Node

2012-10-24 14:56:30

IBMdw

2011-11-10 08:55:00

Node.js
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)