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

 更新时间:2022年09月15日 09:26:03   作者:zxq08  
这篇文章主要介绍了vite如何支持cjs方案示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

一、问题

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

  • 将其他格式(如 UMDCommonJS)的产物转换为 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的方式输出。

  • commonJSesm的区别在哪里?

让我们先看一段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方案的资料请关注脚本之家其它相关文章!

相关文章

  • vue项目中main.js使用方法详解

    vue项目中main.js使用方法详解

    main.js是我们的入口文件,主要作用是初始化vue实例,并引入所需要的插件,下面这篇文章主要给大家介绍了关于vue项目中main.js使用方法的相关资料,需要的朋友可以参考下
    2022-07-07
  • vue中Axios添加拦截器刷新token的实现方法

    vue中Axios添加拦截器刷新token的实现方法

    Axios是一款网络前端请求框架,本文主要介绍了vue中Axios添加拦截器刷新token的实现方法,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • vue键盘事件点击事件加native操作

    vue键盘事件点击事件加native操作

    这篇文章主要介绍了vue键盘事件点击事件加native操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • Vue使用v-model封装el-pagination组件的全过程

    Vue使用v-model封装el-pagination组件的全过程

    通过封装el-pagination组件开发自定义分页组件的类似文章网上已经有很多了,但看了一圈,总是不如意,于是决定还是自己动手搞一个,对v-model封装el-pagination组件相关知识感兴趣的朋友一起看看吧
    2021-07-07
  • 浅谈vue websocket nodeJS 进行实时通信踩到的坑

    浅谈vue websocket nodeJS 进行实时通信踩到的坑

    这篇文章主要介绍了浅谈vue websocket nodeJS 进行实时通信踩到的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • Unocss(原子化css) 使用及vue3 + vite + ts讲解

    Unocss(原子化css) 使用及vue3 + vite + ts讲解

    这篇文章主要介绍了Unocss(原子化css)使用vue3 + vite + ts的方法,简单介绍了Unocss使用及图标库使用,通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • 详解vue后台系统登录态管理

    详解vue后台系统登录态管理

    这篇文章主要介绍了vue后台系统登录管理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 通过Element ui往页面上加一个分页导航条的方法

    通过Element ui往页面上加一个分页导航条的方法

    这篇文章主要介绍了通过Element ui往页面上加一个分页导航条的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 基于Vue+element-ui 的Table二次封装的实现

    基于Vue+element-ui 的Table二次封装的实现

    这篇文章主要介绍了基于Vue+element-ui 的Table二次封装的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • Vue项目总结之webpack常规打包优化方案

    Vue项目总结之webpack常规打包优化方案

    这篇文章主要介绍了vue项目总结之webpack常规打包优化方案,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-06-06

最新评论