Stories

Detail Return Return

解決lodash由於依賴錯誤導致無法啓動的問題 - Stories Detail

目錄

  1. 問題描述
  2. 嘗試的解決辦法
  3. 真正的解決辦法
  4. 結論

一、 問題描述

一個很久沒接觸的老項目,前兩天想看一下里面一個功能,結果前端起不來了。

先上報錯:

image.png


Error: node_modules/@types/lodash/common/object.d.ts:1026:46 - error TS1005: '?' expected.

1026         : K extends `${infer N extends number}` ? T[N]
                                                  ~

Error: node_modules/@types/lodash/common/object.d.ts:1026:51 - error TS2536: Type 'N' cannot be used to index type 'T'.

1026         : K extends `${infer N extends number}` ? T[N]
                                                       ~~~~

Error: node_modules/@types/lodash/common/object.d.ts:1031:46 - error TS1005: '?' expected.

1031         : K extends `${infer N extends number}` ? T[N]
                                                  ~

Error: node_modules/@types/lodash/common/object.d.ts:1031:51 - error TS2536: Type 'N' cannot be used to index type 'T'.

1031         : K extends `${infer N extends number}` ? T[N]
                                                       ~~~~

Error: node_modules/@types/lodash/common/object.d.ts:1041:46 - error TS1005: '?' expected.

1041         : K extends `${infer N extends number}`
                                                  ~

用中文關鍵詞搜了一下,網上有不少類似的問題。

此項目的環境(展示與問題相關的部分):

 "dependencies": {
    // angular 12
    "@angular/common": "~12.1.2",
    "@angular/core": "~12.1.2",
    // lodash
    "lodash": "^4.17.21",
  },
  "devDependencies": {
    // lodash 的 typescript 聲明
    "@types/lodash": "^4.14.182",
    // ts 版本
    "typescript": "~4.3.2"
  }

二、 嘗試的解決辦法

本小節列舉網絡中提到的解決辦法:

更新typescript版本

出處: https://blog.csdn.net/m0_69838795/article/details/140886656

出處2: https://www.cnblogs.com/yalong/p/15502222.html

npm install typescript@latest

這種辦法的問題在於,歷史項目的ts版本是不能動的,一旦ts版本變更就會有更多的組件不滿足依賴要求。

例如Angular 12 要求的版本範圍比較窄:

Error: The Angular Compiler requires TypeScript >=4.2.3 and <4.4.0 but 4.8.4 was found instead.

修改lodash版本 或 @types/lodash 版本

出處: https://cloud.tencent.com/developer/ask/sof/794816

出處2: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/69932

類似的文章中,有兩種説法:

  1. 更新為特定版本,如 @types/lodash@ts2.1.5
  2. 保持@types/lodash和lodash大版本一致

實踐證明,不行。或者説針對特殊情況下才可以,屬於碰運氣而沒有給出原理。

筆者沒有解決。

三、 真正的解決辦法

折騰了一天還沒進展的時候,筆者直接去npm找包了。

搜索lodash看到了它的本體和對應的@types:

image.png

這裏插入一個知識點,這個@types是什麼?

上鍊接:

https://www.tslang.cn/docs/handbook/declaration-files/publish...

https://jkchao.github.io/typescript-book-chinese/typings/type...

通俗的説,拿lodash舉例,lodash本體是js庫,為了在ts中使用,就對這個庫編寫一個對應的聲明文件,以便ts能夠比較好的識別這個庫。

瞭解這個原理後,我們繼續。

看看lodash的版本,沒有什麼發現。只找到了版本號和發佈時間:

image.png

https://www.npmjs.com/package/lodash?activeTab=versions

再來看@types的版本,發現了關鍵:

image.png

https://www.npmjs.com/package/@types/lodash?activeTab=versions

它是有tag的,而tag指明瞭:@types/lodash的版本和ts版本之間的匹配情況。

因此我們得出一個結論:

  • 不是@types/lodashlodash的版本對應
  • 而是@types/lodashts的版本對應

回到本文開頭説的,我們的ts是4.3.2,因此需要找tag為4.3的版本:

image.png

4.14.198可以兼容ts4.3,於是我們安裝這個版本:

npm install @types/lodash@4.14.198

裝好之後,問題迎刃而解:

image.png

四、 結論

最後一小節,來討論一下為什麼好好的項目,同樣的依賴文件,前兩年能跑,現在什麼都沒動,為什麼就跑不了了呢?

  • 我們一般稱npm中的版本為x.y.z
  • x為大版本,x的變化會導致代碼大範圍重構
  • y為中版本,y的變化會導致一些api變化
  • z為小版本,z的變化通常只包含bug修復

來看看@types/lodash的小版本:

image.png

原則上,z的變化不應該造成代碼的重大改動,而上圖中:

  • 4.14.198仍然保留着ts4.3的兼容
  • 但只有小版本變化的4.14.202卻刪掉了ts4.3的兼容

而我們的package.json是這麼寫的:

 "@types/lodash": "^4.14.182",

這裏再引入一個知識點:

  • ^ 表示小版本和中版本可變,大版本不變
  • ~ 表示小版本可變,中版本和大版本不可變

那這個寫法就有問題了,版本已經漂移到不知道哪裏去了。

對於@types/lodash這種小版本變化都會改變兼容性的包,比較穩妥的做法是:

  • 鎖定小版本

這樣基本就解決問題了。

user avatar king_wenzhinan Avatar u_17513518 Avatar journey_64224c9377fd5 Avatar u_13529088 Avatar seazhan Avatar xuxueli Avatar tech Avatar zzger Avatar shumile_5f6954c414184 Avatar eolink Avatar chuanghongdengdeqingwa_eoxet2 Avatar lvlaotou Avatar
Favorites 61 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.