CJS的module.exports 、 exports和ESM export default和 export详解

2024-04-14 06:44

本文主要是介绍CJS的module.exports 、 exports和ESM export default和 export详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

webpackg公共源码

function __webpack_require__(moduleId) {if (__webpack_module_cache__[moduleId]) {return __webpack_module_cache__[moduleId].exports;}var module = __webpack_module_cache__[moduleId] = { exports: {} };__webpack_modules__[moduleId](module, module.exports, __webpack_require__);return module.exports;}

结合源码分析以下问题:

  1. commonjs同时有 module.exports 、 exports 的情况 输出的一直都是 module.exports 导出的内容 ,exports 不生效

    分析:这里简化一下代码,可以结合require方法导入的函数,可以看到module.exports赋值后

    module.exports指向了新的变量,这里和第二个参数已经不是同一个对象了,后面exports.xx只是对临时变量进行赋值,并没有什么意义

    解决办法:
    1.统一用exports
    2.用module.exports,需要格外添加module.exports.xxx=value

    var __webpack_modules__ ={"./src/util/math.ts":(module, exports)=>{module.exports ={sum,sub}exports.sumM = sum;exports.subM = sub,}
    }
    
    • 1.esModule(后面简称ESM)模块用commonJS(简称CJS)的reqiure导入后会多包了一层default
    • 2.ESM export default导出从另一个模块导入后不能直接解构赋值,
    // esModule导出,主要代码
    export const formattedDate2 = (date: Date) => {return date;
    };export default {formattedDate,formattedDate2,
    }
    //index.jsimport esModule, { formattedDate2 } from "./util/format";
    // const { formattedDate } = esModule;
    console.log("esModule", esModule, formattedDate2);
    

    同样的简化源码

     var __webpack_modules__ ={"./src/util/format.ts":(__unused_webpack_module, __webpack_exports__, __webpack_require__)=>{__webpack_require__.d(__webpack_exports__, {"default": () => (__WEBPACK_DEFAULT_EXPORT__),formattedDate2,})const __WEBPACK_DEFAULT_EXPORT__ = ({formattedDate: formattedDate,formattedDate2: formattedDate2})}
    }var _util_format__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(./src/util/format.ts");console.log("esModule", _util_format__WEBPACK_IMPORTED_MODULE_0__["default"], _util_format__WEBPACK_IMPORTED_MODULE_0__.formattedDate2)
    

    这里注意直接导入的是获取_util_format__WEBPACK_IMPORTED_MODULE_0__["default"],而解构赋值是直接调用的_util_format__WEBPACK_IMPORTED_MODULE_0__这就是两者 export default 和 export的区别

    //ESM 特有__webpack_require__.d = function (exports, definition) {for (var key in definition) {if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });}}};// hasOwnProperty() 方法返回一个布尔值,表示对象自有属性(而不是继承来的属性)中是否具有指定的属性__webpack_require__.o = function (obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }
    

    再看 __webpack_require__.d函数对Module执行了什么操作,通过Object.defineProperty给exports分别声明defaultformattedDate2 属性 的getter方法和声明该属性可枚举

    注意这里没有导出setter方法,所以是不能直接修改导出的变量的,但是我们可以在模块导出setter方法去修改变量(我个人觉得有点像私有变量)。

    // esModule增加如下导出,
    let value = "old";
    const setName = (newValue: string) => {value = newValue;
    };export { value, setName };
    //编译的源码如下
    __webpack_require__.d(__webpack_exports__, {"default": () => (__WEBPACK_DEFAULT_EXPORT__),formattedDate2: () => formattedDate2,setName: () => setName,value: () => value
    }
    

这里回过头看问题就清晰了,问题一require导出ESM模块的默认导出一致(看的webpack教程说以前不一样,可能是webpack5修改的),问题2同上,默认导出的是default属性不能直接解构赋值的

这篇关于CJS的module.exports 、 exports和ESM export default和 export详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/902344

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Python中 try / except / else / finally 异常处理方法详解

《Python中try/except/else/finally异常处理方法详解》:本文主要介绍Python中try/except/else/finally异常处理方法的相关资料,涵... 目录1. 基本结构2. 各部分的作用tryexceptelsefinally3. 执行流程总结4. 常见用法(1)多个e

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MySQL8 密码强度评估与配置详解

《MySQL8密码强度评估与配置详解》MySQL8默认启用密码强度插件,实施MEDIUM策略(长度8、含数字/字母/特殊字符),支持动态调整与配置文件设置,推荐使用STRONG策略并定期更新密码以提... 目录一、mysql 8 密码强度评估机制1.核心插件:validate_password2.密码策略级

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

详解python pycharm与cmd中制表符不一样

《详解pythonpycharm与cmd中制表符不一样》本文主要介绍了pythonpycharm与cmd中制表符不一样,这个问题通常是因为PyCharm和命令行(CMD)使用的制表符(tab)的宽... 这个问题通常是因为PyCharm和命令行(CMD)使用的制表符(tab)的宽度不同导致的。在PyChar