好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

详解vite如何支持cjs方案示例

一、问题

vite 运行时使用 esbuild , 基于 esm 大部分三方包为 UMD 规范, 输出的是 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 提供了 预构建阶段 ,主要用于处理两种情况:

将其他格式(如 UMD 和 CommonJS )的产物 转换为 ESM ,以 react 为例, 本文主要记录这种情况的处理。 解决 esm 包 请求瀑布流 的问题,以 lodash-es 为例

三、如何处理commonJS

vite 自动开启了预构建,启动成功后可以在 node_modules/.vite/deps/react.js 看到预构建以后的 react(esm)包

很简单一句,调用了 chunk 中的 require_react 方法,让我们进入 chunk 文件。

此处可以看到 require_react 传入了一个方法给 __commonJS ,并返回了一个新的方法 __require 。

这里有个令人迷惑的点,就是用到了 , 逗号表达式,总会返回后面的内容,这句猜测是因为压缩代码导致的,其效果相当于:

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 的导出内容 cv 了一遍,并赋值给了 mod.exports :

最后看回来到 node_modules/.vite/deps/react.js :

这句相当于 export default mod.exports ,将 react 的模块用 esm 的方式输出。

commonJS 和 esm 的区别在哪里?

让我们先看一段 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 中的导出方式都是基于 module.exports 的,而在 ESM 中,有两种不同的导入/导出方式,分别是 export { name } , export default name 。

因此在把 CommonJS 转换为 ESM 时,需要同时导出两种形式,这样很麻烦。(如果不同时导出两种形式,会导致引入时,有一种对应情况无法使用,理论上只用其中一种对应的方式也可以使用)

如何兼容两种 ESM 的导入/导出形式

此处参考了别的大佬的笔记( vite 预构建的代码也是这么实现的):

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方案示例的详细内容,更多关于vite支持cjs方案的资料请关注其它相关文章!

查看更多关于详解vite如何支持cjs方案示例的详细内容...

  阅读:50次