1 node环境下运行

新建一个文件夹testImport,创建webpack.config.js文件,创建src/index.js 内容为空。

执行npm init

安装第三方工具 npm install airspeed

目录结构如下:

index.js写入测试内容:


import isEmptyObject from 'airspeed/isEmptyObject';// const isEmptyObject = require('airspeed/isEmptyObject');const d = {name: 'maile'}console.log(isEmptyObject(d))module.exports = d;

node src/index.js

会提示错误信息:SyntaxError: Cannot use import statement outside a module。

这是因为用node去执行index.js文件的时候,该文件运行在node环境下,支持的是CommonJs规范,不支持ES6。

const isEmptyObject = require('airspeed/isEmptyObject');

换成上面的方式进行引入,可以正常执行。

2 webpack编译

如果想让index.js文件支持es6模块,需要经过webpack编译后再使用。来配置下webpack:


const path = require('path')
const config = {mode: 'development',entry: './src/index.js',output: {filename: `main.min.js`,path: path.resolve(__dirname, 'dist'),}
}module.exports = config;

安装:npm install webpack@4 webpack-cli -D

主意:目前还没有使用babel,仅仅使用了webpack来进行打包。

"scripts": {"build": "webpack","test": "echo \"Error: no test specified\" && exit 1"},

修改src/index.js


import isEmptyObject from 'airspeed/isEmptyObject';// const isEmptyObject = require('airspeed/isEmptyObject');const d = {name: 'maile'}console.log(isEmptyObject(d))export default d;

注意:引入和导出使用规范保持一致。

执行npm run build

运行 node .\dist\main.min.js

可以看到控制台打印出了false。

再看下"airspeed/isEmptyObject"的导出方式:

node_modules/airspeed/isEmptyObject.js

/*** * @desc   判断`obj`是否为空* @param {Object} obj * @returns {Boolean}*/function isEmptyObject(obj) {if(!obj || typeof obj !== 'object' || Array.isArray(obj)) {return false;}return !Object.keys(obj).length;
}
module.exports = isEmptyObject;

这个文件是用commonJs的规范导出的。后使用的过程中是用es6的规范引入的,经过webpack打包后,就支持了混合使用。

3 分析原因

先来看下webpack打包后的文件:

main.min.js

/******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/        }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/        }
/******/        Object.defineProperty(exports, '__esModule', { value: true });
/******/    };
/******/
/******/    // create a fake namespace object
/******/    // mode & 1: value is a module id, require it
/******/    // mode & 2: merge all properties of value into the ns
/******/    // mode & 4: return value when already ns object
/******/    // mode & 8|1: behave like require
/******/    __webpack_require__.t = function(value, mode) {
/******/        if(mode & 1) value = __webpack_require__(value);
/******/        if(mode & 8) return value;
/******/        if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/        var ns = Object.create(null);
/******/        __webpack_require__.r(ns);
/******/        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/        if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/        return ns;
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = "./src/index.js");
/******/ })
/************************************************************************/
/******/ ({/***/ "./node_modules/airspeed/isEmptyObject.js":
/*!************************************************!*\!*** ./node_modules/airspeed/isEmptyObject.js ***!\************************************************/
/*! no static exports found */
/***/ (function(module, exports) {eval("/**\r\n * \r\n * @desc   判断`obj`是否为空\r\n * @param {Object} obj \r\n * @returns {Boolean}\r\n */\r\n\r\nfunction isEmptyObject(obj) {\r\n  if(!obj || typeof obj !== 'object' || Array.isArray(obj)) {\r\n    return false;\r\n  }\r\n  return !Object.keys(obj).length;\r\n}\r\nmodule.exports = isEmptyObject;\n\n//# sourceURL=webpack:///./node_modules/airspeed/isEmptyObject.js?");/***/ }),/***/ "./src/index.js":
/*!**********************!*\!*** ./src/index.js ***!\**********************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! airspeed/isEmptyObject */ \"./node_modules/airspeed/isEmptyObject.js\");\n/* harmony import */ var airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0__);\n\r\n\r\n\r\n// const isEmptyObject = require('airspeed/isEmptyObject');\r\n\r\nconst d = {name: 'maile'}\r\n\r\nconsole.log(airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0___default()(d))\r\n\r\n/* harmony default export */ __webpack_exports__[\"default\"] = (d);\n\n//# sourceURL=webpack:///./src/index.js?");/***/ })/******/ });

简化一下上面的代码如下:

 (function(modules) { // webpackBootstrap// The require functionfunction __webpack_require__(moduleId) {// Create a new module (and put it into the cache)var module = {i: moduleId,l: false,exports: {}};// Execute the module functionmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);// Return the exports of the modulereturn module.exports;}// Load entry module and return exportsreturn __webpack_require__("./src/index.js");})({"./node_modules/airspeed/isEmptyObject.js":(function(module, exports) {// ./node_modules/airspeed/isEmptyObject.js的内容}),"./src/index.js":(function(module, __webpack_exports__, __webpack_require__) {"use strict";//    ./src/index.js})});

这样看着就是不是清晰多了,一个自动执行的函数,入参是 modulesmodules是一个对象,key为入口文件和所依赖文件的路径,value是一个函数,函数体内部是处理后的文件内容。

先来看自执行函数内部,定义了一个webpack_require函数,并且

returnwebpack_require("./src/index.js"),入参是入口文件。

这个webpack_require 函数内部定义了一个module对象,带有exports属性。调用的时候会传递module,和module.exports。

modules[moduleId].call(module.exports, module, module.exports, _webpack_require); 这里调用的就是自执行函数的入参,找到对应的路径key,调用对应的函数。

"./node_modules/airspeed/isEmptyObject.js":(function(module, exports) {eval("/**\r\n * \r\n * @desc   判断`obj`是否为空\r\n * @param {Object} obj \r\n * @returns {Boolean}\r\n */\r\n\r\nfunction isEmptyObject(obj) {\r\n  if(!obj || typeof obj !== 'object' || Array.isArray(obj)) {\r\n    return false;\r\n  }\r\n  return !Object.keys(obj).length;\r\n}\r\nmodule.exports = isEmptyObject;\n\n//# sourceURL=webpack:///./node_modules/airspeed/isEmptyObject.js?");}),

eval内部的module.exports = isEmptyObject,访问到的就是函数入参就是webpack_require函数中定义的module。

"./src/index.js":(function(module, __webpack_exports__, __webpack_require__) {"use strict";eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! airspeed/isEmptyObject */ \"./node_modules/airspeed/isEmptyObject.js\");\n/* harmony import */ var airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0__);\n\r\n\r\n\r\n// const isEmptyObject = require('airspeed/isEmptyObject');\r\n\r\nconst d = {name: 'maile'}\r\n\r\nconsole.log(airspeed_isEmptyObject__WEBPACK_IMPORTED_MODULE_0___default()(d))\r\n\r\n/* harmony default export */ __webpack_exports__[\"default\"] = (d);\n\n//# sourceURL=webpack:///./src/index.js?");})

上面函数入参webpack_exports就是webpack_require函数中定义的module.exports。而webpack_require就是webpack_require这个函数。

看到eval的第一句先执行了一个函数webpack_require.r(_webpack_exports),这个函数如下:

/******/     // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/        }
/******/        Object.defineProperty(exports, '__esModule', { value: true });
/******/    };

大概意思就是标记一个这个文件使用的是es6规范导出的。

src/index.js文件中第一行内容:

import isEmptyObject from 'airspeed/isEmptyObject';

输入为webpack_require(/*! airspeed/isEmptyObject */ \"./node_modules/airspeed/isEmptyObject.js\")。

可以看出无论是以es6规范导出还是以CommonJs规范导出,最终都会被挂在webpack_require函数中定义的module对象上。当然,引入也是如此。

所以如果你的项目使用了webpack进行打包,就放心了混合使用两种方式了。

为什么CommonJS和ES6可以混合使用?相关推荐

  1. AMD、CMD、CommonJS、ES6(import/export)

    AMD.CMD.CommonJS.ES6(import/export) AMD.CMD.CommonJS是ES5模块化解决方案 AMD -- 异步模块 Asynchronous Module Defi ...

  2. 模块化(AMD、CMD、CommonJS、ES6)

    1,CommonJS 服务器,同步加载模块,加载机制是:输出拷贝 模块导出:module.exports 导入模块:require 2,AMD(异步模块定义) 用于浏览器,防止js加载阻塞页面渲染,异 ...

  3. 模块打包之CommonJS与ES6模块比较初探

    Time: 20190920 模块是具有特定功能的组成单元,不同模块负责不同的工作,然后会以某种方式联系到一起,形成完整的程序逻辑. CommonJS CommonJS是2009年社区提出的,包含模块 ...

  4. es6 混合commjs_前端模块化——CommonJS、ES6规范

    什么叫模块化? 对于一个复杂的程序,将其按照一定的规范封装成几个文件块,每一块向外暴露一些接口,但是块的内部数据是私有的,块与块之间通过接口通信.这个过程称为模块化. 模块化的好处 CommonJS ...

  5. es6模块化机制及CommonJS与ES6模块化规范区别

    模块化机制 CommonJS模块化规范 导入 1. let { firstName, lastName } = require('./1-module.js') 导出 1. module.export ...

  6. 03.06 随手记(AMD、CMD、CommonJS、ES6 Module的区别)

    ***当前阶段的笔记 *** 「面向实习生阶段」https://www.aliyundrive.com/s/VTME123M4T9 提取码: 8s6v 点击链接保存,或者复制本段内容,打开「阿里云盘」 ...

  7. commonjs、ES6的模块暴露和模块引入

    一.commonjs commonjs是作用于服务端应用程序,让js程序具有模块化功能的一种语法规范,执行方式是同步且运行时加载. (一).module.exports 导出 定义一个匿名对象,将需要 ...

  8. Requirejs与r.js打包,AMD、CMD、UMD、CommonJS、ES6模块化

    一:require.js 1.require.js是什么?为什么要用它? require.js是一个JavaScript模块载入框架,实现的是AMD规范.使用require.js有以下优点: ① 异步 ...

  9. 五、Vue模块化开发学习笔记——JavaScript原始功能、匿名函数的解决方案、使用模块作为出口、CommonJS、ES6 export和import的使用

    一.JavaScript原始功能 -在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那个时候代码还是很少的. 那个时候的代码是怎么写的呢? 直接将代码写在<scri ...

最新文章

  1. mvc:interceptor 不起作用的一个解决方法
  2. 报错Submitted credentials for token did not match the expected credentials
  3. 02_创建Git仓库,克隆仓库,git add,git commit,git push,git pull,同行冲突,不同行冲突的结局方案,git mergetool的使用
  4. python实现redis分布式锁
  5. mysql vb_vb连接mysql
  6. JavaScript:学习笔记(3)——正则表达式的应用
  7. 简易网络视频播放器android
  8. java创建项目出现怎么办_maven创建项目后main/java missing的解决方法
  9. java 人脸识别博客
  10. 全球最值得模仿的500个网站(扫描版pdf)
  11. VARCHAR2 与 NVARCHAR2 区别
  12. 6步解决win7局域网内传输慢的问题
  13. 郑州等保测评公司有哪些?在哪里?
  14. 搬家后计算机总重启,电脑无故重启是这一个月来的事了,我刚刚搬家电脑搬到新家那用了没几 爱问知识人...
  15. Arcgis地图切片专题(关于tpk的制作以及迁移切片包至服务器的相关流程)
  16. 在线购物系统 分析类或问题域类图
  17. 高数-数列极限与函数极限
  18. gem5下用se模式运行自己的测试程序
  19. 小车运料c语言编程,西门子PLC编程实例及技巧(运料小车控制系统)
  20. 电桥-20151208

热门文章

  1. 使用mod_status模块监控apache服务
  2. 我们人人都有精神病,努力要做的是…
  3. 如何彻底禁止 macOS Monterey 自动更新,去除更新标记和通知
  4. 高级软件工程-课程总结
  5. Github配置DNS
  6. 【网站监控】如何监控自己的网站(接口)
  7. 笔试 - 2014创新工场涂鸦移动校园招聘测试题 及 答案
  8. delphi 中 delete的用法
  9. CentOS 7 服务器搭建
  10. 传世aft不显示服务器列表,AFT命令转彩虹命令对照表