突然發現,npm里request依賴包已經棄用,怎麼辦?

摘要:在npm官網查看了request依賴包的當前狀態,果然在2020年就被棄用了。

本文分享自華為雲社區《npm里request依賴包已經棄用?致敬並調研替代方案!》,作者: gentle_zhou。

在這個月的程式碼審視中,發現一個js項目里仍然在使用request依賴包進行下載操作,依稀記得這個依賴包應該在2019年就已經進入維護狀態了(即只會維護當前程式碼,修復bug,但不會接收新特性或則發行主要版本)。

加上最近在做MD5文件校驗,但是每次對通過request方法下載下來的資源進行MD5求值,獲得的結果都不一樣,於是就對request依賴包產生了懷疑(後來經過開發測試發現,其實和request依賴包沒啥關係,request仍然可以使用;但是因為是棄用狀態,還是建議替換掉)。

於是立馬上npm官網去查看了下這個依賴包的當前狀態,果然在2020年就被棄用了。官網的鏈接://www.npmjs.com/package/request。

為何request依賴包被棄用

官網介紹說,2020年2月11日,npm依賴包就完全被棄用了(即不會有任何新的改變了);這是非常遺憾的,這個2009年出現的依賴包可以說是JavaScript生態世界裡非常重量級的一款。

在2019年的時候,就有41K的模組依賴它在做下載操作,每周還有14,000,000的下載量。

這麼大量的使用和下載,導致開發者認為這會給依賴包帶來兩個顯著的不好的效應:1.對於新的開發類似需求的依賴包來說會變的很困難,因為request當前佔據了生態系統(Respect! ∠(°^°)); 2.這麼大量的依賴與使用,導致未來任何有意義的改變(顯著的改變)請求的執行都會非常困難,因為這種改變不僅可能不被它的大多數依賴項所採用,而且還會使它與成千上萬的使用request依賴包的部落格和堆棧溢出響應不一致。

再加上隨著JS的發展,在某些特定情況下,request依賴包的核心部分已經跟不上時代潮流了。比如說,大部分開發人員會用async/await和promises搭配一起,這個模式在版本8的Node.js里第一次被使用,但是request並不支援。這時候開發者所說的第二個不好的效應就限制了request去發展去改變(對request進行顯著的改變可能會導致非常多的衝突)。

因此,這個在2022年2月14日去查看的時候github上被star了25.4K的項目就在2020年2月11日處於被棄用狀態了。RIP。

request依賴包是幹嘛用的

先上一張npm官網關於request依賴包的截圖介紹:

我們從圖中介紹,可以看出這相當於是一個非常容易使用的簡單的HTTP客戶端(實際使用過程中也確實非常好用簡易);request依賴包被創建的作用就是用來可以幫助用戶簡單地處理HTTP調用,它能幫助用戶做配置工作,為用戶省去很多複雜的工作(比如配置HTTP連接到代理,或則做一個POST請求)。

最簡單的實踐操作使用方法如下(就是引用一下依賴包,然後request去下載,返回error, response, body資訊):

const request = require('request');
request('//www.google.com', function (error, response, body) {
  console.error('error:', error); // Print the error if one occurred
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
  console.log('body:', body); // Print the HTML for the Google homepage.
});

request依賴包的替代方案

那麼有沒有request的替代方案可以讓我們使用呢?我在做了一番調研之後,發現了下面這些依賴於最新的Node.js-8.x的「流行爆款」依賴包:

    1. Got:Human-friendly and powerful HTTP request library for Node.js。用戶友好的輕量級HTTP請求庫。
      //www.npmjs.com/package/got
    2. Axios:Promise-based HTTP client for the browser and Node.js。
      //www.npmjs.com/package/axios
    3. Node Fetch:A light-weight module that brings window.fetch to Node.js。一個輕量級的HTTP請求庫,它將瀏覽器的Fetch API功能引入Node.js。
      //www.npmjs.com/package/node-fetch
    4. Superagent:Small progressive client-side HTTP request library, and Node.js module with the same API sporting many high-level HTTP client features.一個類似於Axios的流行HTTP庫,用於在Node.js和瀏覽器中發出AJAX請求。
      //www.npmjs.com/package/superagent

幾款依賴包支援的功能等性能比較,可以參考下圖:

因此,通過上圖以及我們實際測試,得出下面結論:

    • Axios有更多的日/周/月下載量,github上獲得更多星;更多的followers和更多的fork,支援在browser上使用,但進度展示僅支援在瀏覽器上顯示。
    • Got有更多的版本,更頻繁的更新,更少的open issues和更少的open pull requests,但是有個明顯的issue(根據我們團隊謝漢華wx1079540 的測試):下載最新版本的12.0.1,使用起來會有錯誤-使用await go引入包會導致no response,僅僅使用got引入包會導致”Must use import to load ES Module:”告警
      – //github.com/sindresorhus/got/discussions/1978
      而如果使用前一個版本11.8.3,則會發生在網頁CloudIDE上連接超時的錯誤(懷疑和proxy有關):
      – //github.com/sindresorhus/got/issues/1572。

還有一種替代方案是直接使用Node.js標準庫里的HTTP 和 HTTPS模組,無需安裝外部軟體包,但是同樣地也會帶來弊端就是使用起來並不友好,會繁瑣很多。

這裡感謝小夥伴的鏈接分享~

  1. //www.twilio.com/blog/2017/08/http-requests-in-node-js.html
  2. //cloud.tencent.com/developer/article/1735008
  3. //nodejs.cn/learn/making-http-requests-with-nodejs/#執行-get-請求

程式碼demo:

const https = require('https');

https.get(url, (res : any) => {
  console.log(`狀態碼: ${res.statusCode}`)

  res.on('data', d => {
    process.stdout.write(d)
  })
 
  res.on('end', () => {
    console.log(`已結束`)
  })
}).on('error', error => {
      console.error(error)
})

註:

針對JS項目里的流式下載,並不僅僅是https.get(requestUrl)下載完之後,就真的下載完了;我們還需要對const stream = fs.createWriteStream(toolsPath);這個stream常量進行檢測,看是否是finish狀態了。

當https.get是end狀態和stream是finish狀態的時候,我們才可以說所有下載都完成了;此時才可以進行MD5值的校驗。

參考鏈接

 

  1. //www.npmjs.com/package/request
  2. //betterprogramming.pub/request-has-been-deprecated-a76415b4910b?gi=3fd5d3ad02db
  3. //github.com/request/request/issues/3142

 

點擊關注,第一時間了解華為雲新鮮技術~