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


  • 2017-02-09 09:02:26

    两列布局——左侧宽度固定,右侧宽度自适应的两种方法

     关于左侧宽度固定,右侧宽度自适应两列布局的一种很常用的方法我相信大家都知道。就是利用左侧元素浮动,或者绝对定位的方式使其脱离常规文档流,让两个块级元素能够在同一行显示。然后右侧元素 margin-left 的值等于左侧元素宽度,这时右侧元素将紧挨着左侧元素

  • 2017-02-10 15:19:51

    Git:代码冲突常见解决方法

    如果系统中有一些配置文件在服务器上做了配置修改,然后后续开发又新添加一些配置项的时候, 在发布这个配置文件的时候,会发生代码冲突:

  • 2017-02-10 15:24:14

    linux学习之——vim简明教程

    学习 vim 并且其会成为你最后一个使用的文本编辑器。没有比这个更好的文本编辑器了,非常地难学,但是却不可思议地好用。 我建议下面这四个步骤: 存活 感觉良好 觉得更好,更强,更快 使用VIM的超能力

  • 2017-02-10 16:22:13

    git历史记录查询

    查看提交历史:git log 查看提交历史并显示版本间的差异:git log -p 查看指定历史:git log xxx(sha1值) -p 查看提交历史(指定时间):

  • 2017-02-13 17:50:05

    cURL error 60: SSL certificate problem: unable to get local issuer certificate

    Drupal 8 version uses Guzzle Http Client internally, but under the hood it may use cURL or PHP internals. If you installed PHP cURL on your PHP server it typically uses cURL and you may see an exception with error Peer certificate cannot be authenticated with known CA certificates or error code CURLE_SSL_CACERT (60).