摘要:本文就來(lái)說(shuō)下這幾個(gè)字段的使用場(chǎng)景,以及同時(shí)存在這幾個(gè)字段時(shí),他們之間的優(yōu)先級(jí)。當(dāng)存在和這種同名不同后綴的文件時(shí),或者是會(huì)優(yōu)先加載文件的。或者優(yōu)先級(jí)是通過(guò)直接執(zhí)行腳本只有字段有效。
browser VS module VS main
前端開發(fā)中使用到 npm 包那可算是家常便飯,而使用到 npm 包總免不了接觸到 package.json 包配置文件。
那么這里就有一個(gè)問(wèn)題,當(dāng)我們?cè)诓煌h(huán)境下 import 一個(gè) npm 包時(shí),到底加載的是 npm 包的哪個(gè)文件?
老司機(jī)們很快地給出答案:main 字段中指定的文件。
然而我們清楚 npm 包其實(shí)又分為:
只允許在客戶端使用的,
只允許造服務(wù)端使用的,
瀏覽器/服務(wù)端都可以使用。
如果我們需要開發(fā)一個(gè) npm 包同時(shí)兼容支持 web端 和 server 端,需要在不同環(huán)境下加載npm包不同的入口文件,顯然一個(gè) main 字段已經(jīng)不能夠滿足我們的需求,這就衍生出來(lái)了 module 與 browser 字段。
本文就來(lái)說(shuō)下 這幾個(gè)字段的使用場(chǎng)景,以及同時(shí)存在這幾個(gè)字段時(shí),他們之間的優(yōu)先級(jí)。
文件優(yōu)先級(jí)在說(shuō) package.json 之前,先說(shuō)下文件優(yōu)先級(jí)
由于我們使用的模塊規(guī)范有 ESM 和 commonJS 兩種,為了能在 node 環(huán)境下原生執(zhí)行 ESM 規(guī)范的腳本文件,.mjs 文件就應(yīng)運(yùn)而生。
當(dāng)存在 index.mjs 和 index.js 這種同名不同后綴的文件時(shí),import "./index" 或者 require("./index") 是會(huì)優(yōu)先加載 index.mjs 文件的。
也就是說(shuō),優(yōu)先級(jí) mjs > js
browser,module 和 main 字段 字段定義main : 定義了 npm 包的入口文件,browser 環(huán)境和 node 環(huán)境均可使用
module : 定義 npm 包的 ESM 規(guī)范的入口文件,browser 環(huán)境和 node 環(huán)境均可使用
browser : 定義 npm 包在 browser 環(huán)境下的入口文件
使用場(chǎng)景與優(yōu)先級(jí)首先,我們假定 npm 包 test 有以下目錄結(jié)構(gòu)
----- lib |-- index.browser.js |-- index.browser.mjs |-- index.js |-- index.mjs
其中 *.js 文件是使用 commonJS 規(guī)范的語(yǔ)法(require("xxx")),*.mjs 是用 ESM 規(guī)范的語(yǔ)法(import "xxx")
其 package.json 文件:
"main": "lib/index.js", // main "module": "lib/index.mjs", // module // browser 可定義成和 main/module 字段一一對(duì)應(yīng)的映射對(duì)象,也可以直接定義為字符串 "browser": { "./lib/index.js": "./lib/index.browser.js", // browser+cjs "./lib/index.mjs": "./lib/index.browser.mjs" // browser+mjs }, // "browser": "./lib/index.browser.js" // browser
根據(jù)上述配置,那么其實(shí)我們的 package.json 指定的入口可以有
main
module
browser
browser+cjs
browser+mjs
這 5 種情況。
下面說(shuō)下具體使用場(chǎng)景。
webpack + web + ESM這是我們最常見(jiàn)的使用場(chǎng)景,通過(guò) webpack 打包構(gòu)建我們的 web 應(yīng)用,模塊語(yǔ)法使用 ESM
當(dāng)我們加載
import test from "test"
實(shí)際上的加載優(yōu)先級(jí)是 browser = browser+mjs > module > browser+cjs > main
也就是說(shuō) webpack 會(huì)根據(jù)這個(gè)順序去尋找字段指定的文件,直到找到為止。
然而實(shí)際上的情況可能比這個(gè)更加復(fù)雜,具體可以參考流程圖
const test = require("test")
事實(shí)上,構(gòu)建 web 應(yīng)用時(shí),使用 ESM 或者 commonJS 模塊規(guī)范對(duì)于加載優(yōu)先級(jí)并沒(méi)有任何影響
優(yōu)先級(jí)依然是 browser = browser+mjs > module > browser+cjs > main
webpack + node + ESM/commonJS我們清楚,使用 webpack 構(gòu)建項(xiàng)目的時(shí)候,有一個(gè) target 選項(xiàng),默認(rèn)為 web,即進(jìn)行 web 應(yīng)用構(gòu)建。
當(dāng)我們需要進(jìn)行一些 同構(gòu)項(xiàng)目,或者其他 node 項(xiàng)目的構(gòu)建的時(shí)候,我們需要將 webpack.config.js 的 target 選項(xiàng)設(shè)置為 node 進(jìn)行構(gòu)建。
import test from "test" // 或者 const test = require("test")
優(yōu)先級(jí)是: module > main
node + commonJS通過(guò) node test.js 直接執(zhí)行腳本
const test = require("test")
只有 main 字段有效。
node + ESM通過(guò) --experimental-modules 可以讓 node 執(zhí)行 ESM 規(guī)范的腳本(必須是 mjs 文件后綴)
`node --experimental-modules test.mjs
import test from "test"
只有 main 字段有效。
總結(jié)如果 npm 包導(dǎo)出的是 ESM 規(guī)范的包,使用 module
如果 npm 包只在 web 端使用,并且嚴(yán)禁在 server 端使用,使用 browser。
如果 npm 包只在 server 端使用,使用 main
如果 npm 包在 web 端和 server 端都允許使用,使用 browser 和 main
其他更加復(fù)雜的情況,如npm 包需要提供 commonJS 與 ESM 等多個(gè)規(guī)范的多個(gè)代碼文件,請(qǐng)參考上述使用場(chǎng)景或流程圖
本文首發(fā)于 github 博客
如文章對(duì)你有幫助,你的 star 是對(duì)我最大的支持
其他文章:掌握甩鍋技術(shù): Typescript 運(yùn)行時(shí)數(shù)據(jù)校驗(yàn)
還可以這么玩?超實(shí)用 Typescript 內(nèi)置類型與自定義類型
插播廣告:
深圳 Shopee 長(zhǎng)期內(nèi)推
崗位:前端,后端(要轉(zhuǎn)go),產(chǎn)品,UI,測(cè)試,安卓,IOS,運(yùn)維 全都要。
薪酬福利:20K-50K
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/104580.html
摘要:優(yōu)化代碼拆分從入口文件開始,遞歸地構(gòu)建了整個(gè)應(yīng)用的模塊依賴圖表,然后通常會(huì)將所有的模塊打包成一個(gè)。 如果你還不知道什么是React,請(qǐng)點(diǎn)擊這里github源碼 安裝Node.js 如果你還不知道什么是ECMAScript,請(qǐng)點(diǎn)擊這里 如果你還不知道什么是Node.js,請(qǐng)點(diǎn)擊這里 下載Node.js并安裝;接著打開windows命令行窗口分別輸入node -v及npm -v如下圖所示,...
摘要:非官方字段集合官方字段請(qǐng)參考。下面介紹的是非官方字段,也就是各種工具定義的相關(guān)字段。詳細(xì)參考相關(guān)字段設(shè)置項(xiàng)目的瀏覽器兼容情況。相關(guān)字段測(cè)試庫(kù)。相關(guān)字段代碼檢查與優(yōu)化。 package.json 非官方字段集合 package.json 官方字段請(qǐng)參考 https://docs.npmjs.com/files/package.json。下面介紹的是非官方字段,也就是各種工具定義的相關(guān)字段...
摘要:的定位屬于預(yù)處理器嗎還是屬于后置處理器都不是,因?yàn)榫唧w做的事取決于開發(fā)者使用了什么插件。這里做一個(gè)我覺(jué)得比較恰當(dāng)?shù)念惐?,中的相?dāng)于的中的,,等預(yù)處理器相當(dāng)于,雖然不是完全合理,但是還是比較恰當(dāng)。 前言 原諒我取這樣的標(biāo)題,我知道 postCss 對(duì)于大多數(shù)前端開發(fā)者來(lái)說(shuō)早已經(jīng)很熟悉了,但是樓主作為一個(gè)初出茅廬的前端er,還有好多的工具和技術(shù)沒(méi)接觸過(guò),說(shuō)來(lái)慚愧。雖然平時(shí)也喜歡使用css預(yù)...
摘要:的另一種形式測(cè)試踩坑之路代碼覆蓋率單元測(cè)試的代碼覆蓋率統(tǒng)計(jì),是衡量測(cè)試用例好壞的一個(gè)的方法。 showImg(https://segmentfault.com/img/remote/1460000012564211?w=640&h=280); 項(xiàng)目地址: diana文檔地址: http://muyunyun.cn/diana/ 造輪子的意義 為啥已經(jīng)有如此多的前端工具類庫(kù)還要自己造輪...
摘要:使用要給項(xiàng)目構(gòu)建接入動(dòng)態(tài)鏈接庫(kù)的思想,需要完成以下事情把網(wǎng)頁(yè)依賴的基礎(chǔ)模塊抽離出來(lái),打包到一個(gè)個(gè)單獨(dú)的動(dòng)態(tài)鏈接庫(kù)中去。接入已經(jīng)內(nèi)置了對(duì)動(dòng)態(tài)鏈接庫(kù)的支持,需要通過(guò)個(gè)內(nèi)置的插件接入,它們分別是插件用于打包出一個(gè)個(gè)單獨(dú)的動(dòng)態(tài)鏈接庫(kù)文件。 webpack優(yōu)化 查看所有文檔頁(yè)面:全棧開發(fā),獲取更多信息。原文鏈接:webpack優(yōu)化,原文廣告模態(tài)框遮擋,閱讀體驗(yàn)不好,所以整理成本文,方便查找。 ...
閱讀 3143·2021-10-13 09:39
閱讀 2761·2021-09-27 13:34
閱讀 2116·2019-08-30 15:55
閱讀 3306·2019-08-30 15:43
閱讀 3711·2019-08-30 11:16
閱讀 1833·2019-08-26 18:28
閱讀 1404·2019-08-26 13:56
閱讀 1006·2019-08-26 13:35