CommonJs 与 ESModule区别

2021-01-08 16:49:59

参考地址 CommonJs 与 ESModule区别

CommonJs(Node)
  • 模块运行时动态加载

node中模块导入require是一个内置的函数,因此只有在运行后我们才可以得知模块导出内容,无法做静态分析

1
2
const fileName = 'xx.js';
const xx = require(fileName);

  • 默认未开启严格模式

1
2
3
4
5
console.log(this); 
function (){
   console.log(this);// 指向global
}
name();

node中未开启严格模式情况下全局this指向module.exports。

ESModule
  • 默认开启严格模式(‘use strict’)

1
2
3
4
5
console.log(this);// undefined
function (){
   console.log(this);// undefined
}
name();

  • 静态解析

    • 只能作为模块顶层的语句出现,不能出现在 function 里面或是 if 里面

    • import 的模块名只能是字符串常量

    • import 声明提前,在模块顶层

Tree Shaking

利用ES2015(es6)模块语法静态解析的特性,删除没有使用的代码,减小文件大小,对代码进行优化。
webpack 2.0 加入了这一特性。

源码

1
2
3
4
5
6
//export.js
export function a1(){alert('a1')};
export function a2(){alert('a2')};
//import.js
import {a1} from './export.js'
a1('arguments')

压缩后
  • 关闭tree shaking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
!function (modules) {
   function __webpack_require__(moduleId) {
       // ...some code
   }
   var installedModules = {};
   // ...some code
}([
   function (module, exports, __webpack_require__) {
;
       (0, __webpack_require__(1).a1)("arguements")
   },
   function (module, exports, __webpack_require__) {
;
       Object.defineProperty(exports, "__esModule", {
           value: !0
       }),
       exports.a1 = function () {
           alert("!")
       },
       exports.a2 = function () {
           alert("!!")
       }
   }
]);

  • 开启tree shaking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
!function (modules) {
   function __webpack_require__(moduleId) {
       // ...some code
   }
   var installedModules = {};
   // ...some code
}([
   function (module, __webpack_exports__, __webpack_require__) {
;
       Object.defineProperty(__webpack_exports__, "__esModule", {
           value: !0
       });
       var __WEBPACK_IMPORTED_MODULE_0__es6_export__ = __webpack_require__(1);
       Object(__WEBPACK_IMPORTED_MODULE_0__es6_export__.a)("arguements")
   },
   function (module, __webpack_exports__, __webpack_require__) {
;
       __webpack_exports__.a = function () {
           alert("!")
       }
   }
]);

webpack Tree Shaking 开启条件:
  • 使用es2015模块语法(import 与 export)

  • 使用支持无用代码移除(dead code removal)的插件,如 UglifyJSPlugin

  • 去除babel-loder的模块转换插件,交给webpack来做模块转换babel 6.0+ 配置

不足:
  • npm公共包大多不支持es2015 module

  • 与babel兼容做的不好,待babel重启modules属性

结论
  • 浏览器端代码使用es2015 module,模块化使用灵活,且可充分利用Tree Shaking减小代码体积

  • 服务端node适合动态引入且不需要过多考虑代码体积所以使用commonjs规范,同时可以拥有更好的debug支持,提高开发效率

Tips
  • webpack内置uglifyPlugin版本相对较低,建议不使用内置版本,单独安装

  • babel6以下版本只需设置参数modules为false即可,babel6及以上只能列出除去transform-es2015-modules-commonjs所有plugin

  • 建议只import需要的方法,而不是import整个模块,便于去除dead_code


  • 2021-01-13 17:23:21

    CREATE TABLE 表名 AS SELECT 语句 快速复制表但是锁表

    注意Table2的主键约束,如果Table2有主键而且不为空,则 field1, field2…中必须包括主键 在执行语句的时候,MySQL是逐行加锁的(扫描一个锁一个),直至锁住所有符合条件的数据,执行完毕才释放锁。所以当业务在进行的时候,切忌使用这种方法。 在RR隔离级别下,还会加行锁和间隙锁

  • 2021-01-13 17:27:04

    Navicat配置mysql数据库用户权限

    用数据库的时候就会遇到有多个用户,分配用户权限的情况,有些用户只读,有些用户可以读写,有些用户只能操作一个或者多个数据库,如何给mysql的用户设置权限,我这里描述一下如何用navicat图形操作分配用户权限

  • 2021-01-14 06:15:04

    通过glide获取图片显示后的真正宽高

    有时候需要获取网络图片的宽高来设置图片显示的大小,很多人会直接利用Glide的加载监听去拿图片的宽高,但是这样拿到的不是图片真正的宽高,而是图片显示在ImageView后的宽高。如下:

  • 2021-01-14 09:38:57

    Chrome插件详细教程

    严格来讲,我们正在说的东西应该叫Chrome扩展(Chrome Extension),真正意义上的Chrome插件是更底层的浏览器功能扩展,可能需要对浏览器源码有一定掌握才有能力去开发。鉴于Chrome插件的叫法已经习惯,本文也全部采用这种叫法,但读者需深知本文所描述的Chrome插件实际上指的是Chrome扩展。

  • 2021-01-14 17:07:51

    chrome.contextMenus.create不出现菜单

    主要原因是,我每次刷新玩,都复制一下右键,然而并没有出现菜单,一度颓废啊,因为demo,还有其他人的文章都是这样的。 哎,后来发现是这样的,我缺少了contexts选项。其实我是成功了,我现在只要不选择文字,直接点右键,菜单已经出现了哦。

  • 2021-01-15 13:06:08

    监控 MongoDB -

    随着MongoDB中保存的数据越来越多,对MongoDB服务状态的监控也越来越重要,经常关注服务是否健康,才能防止故障以及优化。