詳解vite如何支持cjs方案示例
一、問(wèn)題
vite
運(yùn)行時(shí)使用esbuild
,基于esm
- 大部分三方包為
UMD
規(guī)范,輸出的是CommonJS
的包(比如react
、lodash
)
// react 入口文件 // 只有 CommonJS 格式 if (process.env.NODE_ENV === "production") { module.exports = require("./cjs/react.production.min.js"); } else { module.exports = require("./cjs/react.development.js"); }
二、解決方案
vite
提供了預(yù)構(gòu)建階段,主要用于處理兩種情況:
- 將其他格式(如
UMD
和CommonJS
)的產(chǎn)物轉(zhuǎn)換為ESM
,以react
為例,本文主要記錄這種情況的處理。 - 解決
esm
包請(qǐng)求瀑布流的問(wèn)題,以lodash-es
為例
三、如何處理commonJS
vite
自動(dòng)開(kāi)啟了預(yù)構(gòu)建,啟動(dòng)成功后可以在node_modules/.vite/deps/react.js
看到預(yù)構(gòu)建以后的react(esm)包
很簡(jiǎn)單一句,調(diào)用了chunk
中的require_react
方法,讓我們進(jìn)入chunk
文件。
此處可以看到require_react
傳入了一個(gè)方法給__commonJS
,并返回了一個(gè)新的方法__require
。
這里有個(gè)令人迷惑的點(diǎn),就是用到了,
逗號(hào)表達(dá)式,總會(huì)返回后面的內(nèi)容,這句猜測(cè)是因?yàn)閴嚎s代碼導(dǎo)致的,其效果相當(dāng)于:
function __require() { // 壓縮后 return mod || (0, test)((mod = { exports: {} }).exports, mod), mod.exports; // 壓縮前,僅推測(cè) if (mod) { return mod } else { test(mod, mod.exports) return mod.exports } }; function test(exports, mod) { console.log('exports, mod', exports, mod) }
在接近 1800 行的require_react_development
中,主要是把react
的導(dǎo)出內(nèi)容cv
了一遍,并賦值給了mod.exports
:
最后看回來(lái)到node_modules/.vite/deps/react.js
:
這句相當(dāng)于 export default mod.exports
,將react
的模塊用esm
的方式輸出。
commonJS
和esm
的區(qū)別在哪里?
讓我們先看一段esm
的代碼
// Named export/import export { name } import { name } from "name" // Default export/import export default name import name from "name"
再看一段CommonJS
let name = { firstName, lastName } module.exports = name mudule.export.firstName = 'z' exports.lastName = 'zz'
不難看出,在CommonJS
中的導(dǎo)出方式都是基于module.exports
的,而在ESM
中,有兩種不同的導(dǎo)入/導(dǎo)出方式,分別是export { name }
,export default name
。
因此在把CommonJS
轉(zhuǎn)換為ESM
時(shí),需要同時(shí)導(dǎo)出兩種形式,這樣很麻煩。(如果不同時(shí)導(dǎo)出兩種形式,會(huì)導(dǎo)致引入時(shí),有一種對(duì)應(yīng)情況無(wú)法使用,理論上只用其中一種對(duì)應(yīng)的方式也可以使用)
- 如何兼容兩種
ESM
的導(dǎo)入/導(dǎo)出形式
此處參考了別的大佬的筆記(vite
預(yù)構(gòu)建的代碼也是這么實(shí)現(xiàn)的):
var esm$1 = { exports: {} }; (function (module, exports) { module.exports = () => {}; exports.a = 3; exports.b = 4; })(esm$1, esm$1.exports); var esm = esm$1.exports; export { esm as default };
以上就是詳解vite如何支持cjs方案示例的詳細(xì)內(nèi)容,更多關(guān)于vite支持cjs方案的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue引入并使用Element組件庫(kù)的兩種方式小結(jié)
本文主要介紹了Vue引入并使用Element組件庫(kù)的兩種方式小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01前端vue打包項(xiàng)目,如何解決跨域問(wèn)題
這篇文章主要介紹了前端vue打包項(xiàng)目,如何解決跨域問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05Vue使用jsmind實(shí)現(xiàn)生成腦圖的示例代碼
這篇文章主要為大家詳細(xì)介紹了Vue如何使用jsmind實(shí)現(xiàn)生成腦圖,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2024-03-03解決vue中el-date-picker?type=daterange日期不回顯的問(wèn)題
這篇文章主要介紹了解決vue中el-date-picker?type=daterange日期不回顯的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vue頁(yè)面使用阿里oss上傳功能的實(shí)例(一)
本篇文章主要介紹了vue頁(yè)面使用阿里oss上傳功能的實(shí)例(一),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08Vue3使用setup監(jiān)聽(tīng)props實(shí)現(xiàn)方法詳解
這篇文章主要為大家介紹了Vue3使用setup監(jiān)聽(tīng)props實(shí)現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08