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


  • 2020-02-22 18:03:10

    Vue组件中使用Sass或者Less全局变量

    本文以Sass做案例,Less的参考,基本配置大同小异。 假如我们有一个Sass的全局变量common.scss文件,路径 ../style/common.scss 代码如下:

  • 2020-02-23 23:27:26

    Nuxt.js 基础入门教程

    Nuxt.js 就是一个极简的 vue 版的 ssr 框架。基于它,我们可以快速开发一个基于 vue 的 ssr 单页面应用。

  • 2020-02-24 18:36:17

    百度地图做电子围栏总结

    需求:在地图上画出围栏,设置围栏信息后保存,生成围栏列表。全选时,地图视野可看到全部的围栏区域,单独勾选会调整地图视野到当前勾选的围栏。围栏区域的中心点要显示围栏名称。

  • 2020-02-24 18:37:17

    百度地图绘制轨迹点

    没有后台获取事实信息 都是伪数据- -轨迹信息做不到事实导航。 控件可以根据自己的需求添加 位置通过offset:new BMAP.Size(x,y)进行微调 事实路况信息需要通过引没有后台获取事实信息 都是伪数据- -轨迹信息做不到事实导航。 控件可以根据自己的需求添加 位置通过offset:new BMAP.Size(x,y)进行微调 3D视图部分城市没有开放开放 根据需求自己添加

  • 2020-02-24 18:43:54

    百度地图JS关于规划路线偏离预警的解决方式

    说实在的这个解决方案有点low,我并不会很赞成,效率有点低。如果多的话,很是耗费资源。 我推荐使用矩形来解决这个问题,而不是圆形。 当日用矩形的话,就要确保轨迹是折线的,而不是弧线等。

  • 2020-02-24 18:45:33

    巧妙解决百度地图加偏纠偏问题

    所谓的加偏,就是将真实坐标加上一定的偏移量,而这个偏移量又不是线性的,不同地区偏移不一样,但同一地区偏移量却差不多,因此,有人就使用了个暴力破解的方法,

  • 2020-02-24 18:48:34

    规划驾车路线和途径点及判断车辆路线偏移

    项目需求需要利用百度地图构建路线并支持设置途径点,以及可以实时监控车辆是否偏移路线;两种方案。 写了比较完整的注释了,替换ak可直接看效果,规划驾车路线和途径点及判断车辆路线偏移