詳解vite如何支持cjs方案示例
一、問題
vite運行時使用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包請求瀑布流的問題,以lodash-es為例

三、如何處理commonJS
vite自動開啟了預(yù)構(gòu)建,啟動成功后可以在node_modules/.vite/deps/react.js看到預(yù)構(gòu)建以后的react(esm)包

很簡單一句,調(diào)用了chunk中的require_react方法,讓我們進(jìn)入chunk文件。

此處可以看到require_react傳入了一個方法給__commonJS,并返回了一個新的方法__require。
這里有個令人迷惑的點,就是用到了,逗號表達(dá)式,總會返回后面的內(nèi)容,這句猜測是因為壓縮代碼導(dǎo)致的,其效果相當(dāng)于:
function __require() {
// 壓縮后
return mod || (0, test)((mod = { exports: {} }).exports, mod), mod.exports;
// 壓縮前,僅推測
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:

最后看回來到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時,需要同時導(dǎo)出兩種形式,這樣很麻煩。(如果不同時導(dǎo)出兩種形式,會導(dǎo)致引入時,有一種對應(yīng)情況無法使用,理論上只用其中一種對應(yīng)的方式也可以使用)
- 如何兼容兩種
ESM的導(dǎo)入/導(dǎo)出形式
此處參考了別的大佬的筆記(vite預(yù)構(gòu)建的代碼也是這么實現(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方案的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue引入并使用Element組件庫的兩種方式小結(jié)
本文主要介紹了Vue引入并使用Element組件庫的兩種方式小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
解決vue中el-date-picker?type=daterange日期不回顯的問題
這篇文章主要介紹了解決vue中el-date-picker?type=daterange日期不回顯的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
Vue3使用setup監(jiān)聽props實現(xiàn)方法詳解
這篇文章主要為大家介紹了Vue3使用setup監(jiān)聽props實現(xiàn)方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

