browser
VS module
VS main
前端開發中使用到 npm
包那可算是屢見不鮮,而使用到 npm
包總免不了接觸到 package.json
包配置文件。javascript
那麼這裏就有一個問題,當咱們在不一樣環境下 import
一個 npm
包時,到底加載的是 npm
包的哪一個文件?前端
老司機們很快地給出答案:main
字段中指定的文件。java
然而咱們清楚 npm
包其實又分爲:node
若是咱們須要開發一個 npm
包同時兼容支持 web端 和 server 端,須要在不一樣環境下加載npm包不一樣的入口文件,顯然一個 main
字段已經不可以知足咱們的需求,這就衍生出來了 module
與 browser
字段。webpack
本文就來講下 這幾個字段的使用場景,以及同時存在這幾個字段時,他們之間的優先級。git
在說 package.json
以前,先說下文件優先級github
因爲咱們使用的模塊規範有 ESM 和 commonJS 兩種,爲了能在 node 環境下原生執行 ESM 規範的腳本文件,.mjs
文件就應運而生。web
當存在 index.mjs
和 index.js
這種同名不一樣後綴的文件時,import './index'
或者 require('./index')
是會優先加載 index.mjs
文件的。面試
也就是說,優先級 mjs
> js
npm
browser
,module
和 main
字段main
: 定義了 npm
包的入口文件,browser 環境和 node 環境都可使用module
: 定義 npm
包的 ESM 規範的入口文件,browser 環境和 node 環境都可使用browser
: 定義 npm
包在 browser 環境下的入口文件首先,咱們假定 npm
包 test
有如下目錄結構
----- lib
|-- index.browser.js
|-- index.browser.mjs
|-- index.js
|-- index.mjs
複製代碼
其中 *.js
文件是使用 commonJS 規範的語法(require('xxx')
),*.mjs
是用 ESM 規範的語法(import 'xxx'
)
其 package.json 文件:
"main": "lib/index.js", // main
"module": "lib/index.mjs", // module
// browser 可定義成和 main/module 字段一一對應的映射對象,也能夠直接定義爲字符串
"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
複製代碼
根據上述配置,那麼其實咱們的 package.json
指定的入口能夠有
main
module
browser
browser+cjs
browser+mjs
這 5 種狀況。下面說下具體使用場景。
這是咱們最多見的使用場景,經過 webpack
打包構建咱們的 web 應用,模塊語法使用 ESM
當咱們加載
import test from 'test'
複製代碼
實際上的加載優先級是 browser
= browser+mjs
> module
> browser+cjs
> main
也就是說 webpack 會根據這個順序去尋找字段指定的文件,直到找到爲止。
然而實際上的狀況可能比這個更加複雜,具體能夠參考流程圖
const test = require('test')
複製代碼
事實上,構建 web 應用時,使用 ESM
或者 commonJS
模塊規範對於加載優先級並無任何影響
優先級依然是 browser
= browser+mjs
> module
> browser+cjs
> main
咱們清楚,使用 webpack 構建項目的時候,有一個 target 選項,默認爲 web,即進行 web 應用構建。
當咱們須要進行一些 同構項目,或者其餘 node 項目的構建的時候,咱們須要將 webpack.config.js
的 target
選項設置爲 node
進行構建。
import test from 'test'
// 或者 const test = require('test')
複製代碼
優先級是: module > main
經過 node test.js
直接執行腳本
const test = require('test')
複製代碼
只有 main 字段有效。
經過 --experimental-modules
可讓 node 執行 ESM 規範的腳本(必須是 mjs 文件後綴)
`node --experimental-modules test.mjs
import test from 'test'
複製代碼
只有 main 字段有效。
npm
包導出的是 ESM 規範的包,使用 modulenpm
包只在 web 端使用,而且嚴禁在 server 端使用,使用 browser。npm
包只在 server 端使用,使用 mainnpm
包在 web 端和 server 端都容許使用,使用 browser 和 mainnpm
包須要提供 commonJS 與 ESM 等多個規範的多個代碼文件,請參考上述使用場景或流程圖插播廣告:
深圳 Shopee 長期內推
崗位:前端,後端(要轉go),產品,UI,測試,安卓,IOS,運維 全都要。
薪酬福利:20K-50K😳,7點下班😏,免費水果😍,免費晚餐😊,15天年假👏,14天帶薪病假。 點擊查看詳情 簡歷發郵箱:chenweiyu6909@gmail.com 或者加我微信:cwy13920,實時反饋面試進度哦。