天天看點

NPM這6個有趣實用的知識點,你知道幾個??

一、 啥?​

​npm add​

​​ 和 ​

​npm install​

​ 完全等價

注意:是完全等價!

如果你試圖在 ​

​npm​

​​ 官方搜尋 ​

​npm add​

​ 這個指令,你會發現這個指令似乎根本不存在,如下圖:

NPM這6個有趣實用的知識點,你知道幾個??

那我們平時使用的 ​

​npm add vue@latest --save​

​ 又是什麼鬼?

其實,​

​npm add​

​​ 是 ​

​npm install​

​ 的 别名 之一,是以當我們執行 ​

​npm add​

​​ 時,對于 ​

​npm​

​​ 來說完完全全等同于執行了 ​

​npm install​

​!

下次,你可以試試 ​

​npm install vue@latest --save​

​ 了🤣

如你所知,​

​npm install​

​​ 還有另一個常見的别名:​

​npm i​

​;

二、啥?​

​npm isntall​

​​、​

​npm instal​

​ 也能執行?

你沒看錯,上面不是 ​

​install​

​,而是稀奇古怪的拼寫錯誤;

那麼 ​

​npm isntall​

​​、​

​npm instal​

​ 這種錯誤的拼寫指令,執行起來是什麼效果呢?

答案是: 和 ​

​npm install​

​ 一模一樣!

哈哈,沒想到吧!

NPM這6個有趣實用的知識點,你知道幾個??

其實,這是 ​

​npm 8.x​

​ 版本的新特性,可能某個核心貢獻者和你我一樣也是老手殘黨,常年因為 手指跟不上大腦的運算速度 而輸入錯誤的指令。

是以在 ​

​8.x​

​​ 版本,​

​npm install​

​​ 在之前 ​

​add​

​​、​

​i​

​的基礎上增加了 9個别名,它們是:

in, ins, inst, insta, instal, isnt, isnta, isntal, isntall      

媽耶,各種能想到的不能想到的拼寫錯誤都在裡面,這位貢獻者,一定是個有故事的同學。

三、每個 ​

​script​

​ 腳本都有前任與下一任?

你目前所開發的項目裡定義的建構指令是什麼?

假如,建構腳本是:

npm run build      

那麼你知道如何在執行 ​

​npm run build​

​ 指令執行之前,做一些特定的别的操作,或者在執行之後執行一些操作,應該怎麼做嗎?

答案是定義以下兩個腳本:

{
  "scripts": {
    "prebuild": "",// 這是 build 執行前的鈎子
    "postbuild": "" // 這是 build 執行後的鈎子
  }
}      

哪怕你定義一個腳本叫 ​

​papapa​

​​,也是具備 “前任” ​

​prepapapa​

​​ 和 “下一任” ​

​postpapapa​

​ 這樣的鈎子的!

你是否發現很多元件庫的 ​

​package.json​

​​ 裡都有 ​

​postinstall​

​ 腳本?

沒錯,它們正是在 ​

​install​

​ 執行之後執行的腳本。

四、通過 ​

​npm link​

​,能創造一些實用的工具指令

​npm link​

​ 很多人都知道,它最廣為人知的用途是:

建立一個軟連接配接,使得你可以在不釋出到 ​

​npm​

​​ 源的情況下,在 ​

​B​

​​ 項目裡依賴 ​

​A​

​ 項目進行聯調。

但如果你在項目的 ​

​package.json​

​​ 裡定義了 ​

​bin​

​ 屬性,并将它指向某個可執行的腳本檔案。

比如:

{
  "bin": {
    "i-love-u": "src/index.js"
  }
}      

一旦你在項目裡通過 ​

​npm link​

​​ 釋出了,恭喜你,你隻需要在指令行中輸入 ​

​i-love-u​

​ 就會直接執行它所指向的腳本了。

這難道不 ​

​cooool​

​ 嗎?

這會讓你看起來,更像一個 "極客" 。

五、當你使用依賴時,導入的具體是哪個檔案?

你能告訴我,當你在代碼裡寫下如下代碼時:

import { createStore } from 'vuex';
// 或者是
const { createStore } = require('vuex');      

兩種語句引入的是同一個檔案嗎?差別在哪?

會對程式産生什麼差别嗎?

有些同學或許能回答出 "前者是 ​

​ESM​

​​ 文法,後者是 ​

​CommonJS​

​ 文法。",然後呢?

然後,我們需要先了解幾個知識點:

  1. 從​

    ​node 14.x​

    ​​ 版本開始,​

    ​package.json​

    ​​ 裡支援了​

    ​exports​

    ​ 屬性,當它存在時,它的優先級最高。
// 這說明無論是 import 還是 require 都隻會以 `main.js` 作為入口
"exports": "main.js"

// 以下則可以給 `require` 和 `import` 分别設定入口
"exports": {
  "import": "es/index.js",
  "require": "cjs/index.js"
}      
  1. 當​

    ​exports​

    ​ 屬性不存在,而 ​

    ​module​

    ​ 屬性存在時,建構工具(如 ​

    ​webpack​

    ​、​

    ​rollup​

    ​)會把 ​

    ​module​

    ​ 屬性作為 ​

    ​ESM​

    ​ 的入口來使用。

    是以,如果​

    ​package.json​

    ​ 檔案裡有:
name: "yy",
module: "lib/index.js",      

在 ​

​webpack/rollup​

​ 項目中:

import xx from 'yy';      

入口會被指向 ​

​node_modules/yy/lib/index.js​

  1. 如果​

    ​exports​

    ​​ 和​

    ​module​

    ​​ 都不存在,則​

    ​package.json​

    ​​ 中的​

    ​main​

    ​ 屬性會成為指定入口的唯一屬性。

關于 “子產品入口” 的話題,可以拓展出一整篇文章,是以不再贅述,有興趣的朋友可以自行閱讀 ​

​Node.js​

​ 相關文檔:

nodejs.cn/api/package…

(好吧,嚴格來說,這不屬于 ​

​npm​

​ 的知識點,orz)

六、公源、私源切換,​

​.npmrc​

​ 居然這麼好用?

​npm​

​​ 預設的源是 ​

​https://registry.npmjs.org ​

​。但因為衆所周知的原因,這個源在國内通路起來速度很慢。

此時,我們可以通過以下指令将其設定為 ​

​taobao​

​ 源:

# npm 自帶的設定功能
npm config set registry https://registry.npm.taobao.org
# or
# 如果你安裝了nrm
nrm use taobao      

以上做法雖然有效,但并沒有将 “指定源” 固話在項目配置中,新同學上手時可能需要在這些問題上花費大量精力。

更好的選擇是 ​

​.npmrc​

​ 檔案。

registry = https://registry.npm.taobao.org/
@juejin:registry = https://siyouyuan.org/      

通過 ​

​.npmrc​

​ 檔案可以設定項目級的配置,以上兩行代碼分别做了如下兩件事:

  1. ​@juejin​

    ​ 命名空間的項目,直接在私有源請求包;
  2. 其他包則從​

    ​taobao​

    ​ 源發起請求。

七、結束語