阅读 170

CommonJS和ES6模块有什么区别!

CommonJS和ES6模块有什么区别!

一、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用

commonjs的用法,我们一起来看一下

1.首先创建一个lib.js的文件

// lib.js const counter = 3; const incCounter = ()=>{   counter++ } module.exports = {   counter,   incCounter } 复制代码

2.再次创建一个main.js,使用commonjs的方式导入

// main.js var lib = require('./lib'); console.log(lib) console.log(lib.counter);  // 3 lib.incCounter(); console.log(lib.counter); // 3 复制代码

lib.js模块加载以后,它的内部变化就影响不到输出的lib.counter了。这是因为mod.counter是一个原始类型的值,会被缓存;

esmodule的用法,我们一起来看一下

// lib.js export let counter = 3; export function incCounter () {   counter++; } 复制代码

// main.js import { counter, incCounter } from './util.mjs' console.log(counter);  //3  incCounter() console.log(counter)  //4  复制代码

ES6 模块不会缓存运行结果,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块。

补充:通过esmodule导入的变量是不能重新赋值修改的。

二、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口

// CommonJS模块 let { stat, exists, readFile } = require('fs');   // 等同于 let _fs = require('fs'); let stat = _fs.stat; let exists = _fs.exists; let readfile = _fs.readfile; 复制代码

上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。因此commonjs属于再运行时才会加载模块的方式。

import { stat, exists, readFile } from 'fs'; 复制代码

上面代码的实质是从fs模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高;

三、CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段

同步加载:所谓同步加载就是加载资源或者模块的过程会阻塞后续代码的执行;
异步加载:不会阻塞后续代码的执行;

我们来看一个案例,创建如下的目录;

| -- a.js | -- index.js | -- c.js 复制代码

// a.js console.log('a.js文件的执行'); const importFun = () => {   console.log(require('./c').c); } importFun() module.exports = {   importFun } 复制代码

// index.js const A = require('./a'); console.log('index.js的执行'); 复制代码

// c.js console.log('c.js的运行'); const c = 3 module.exports = {   c } 复制代码

执行命令 node index.js

// a.js文件的执行 // c.js的运行 // 3 // index.js的执行 复制代码

我们会发现,require的内容会阻塞后续代码的执行。因为c.js先打印出来,然后在是index.js的打印,所以说require()是同步加载的;

// a.js console.log('a.js文件的执行'); export const importFun = () => {   import('./c.js').then(({c})=>{     console.log(c)   }) } importFun() 复制代码

// index.js import {importFun} from './a.js' console.log('index.js的执行'); 复制代码

// c.js console.log('c.js的运行'); export const c = 3 复制代码

// 结果 // a.js文件的执行 // index.js的执行 // c.js的运行 // 3 复制代码

可以看的出来:import()是异步加载资源的,因为c.js是在index.js的后面打印出来的,并不会阻塞后续代码的执行;

总结:以上便是commonjs和esmodule的几个区别

1: CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用 2: CommonJS 模块是运行时加载,ES6 模块是编译时输出接口 3: CommonJS 模块的require()是同步加载模块,ES6 模块的import命令是异步加载,有一个独立的模块依赖的解析阶段


作者:Story
链接:https://juejin.cn/post/7048139060983889950

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐