结论 https://zhuanlan.zhihu.com/p/161015809https://zhuanlan.zhihu.com/p/161015809

commonJS ES Module
值 1.基本类型:值复制,不共享
2.引用类型:浅拷贝,共享
3.工作空间可以修改引入的值
1.只读导入,动态读取
2.不可再外部修改引用,但是可以调用引用包含的方法
执行顺序 1.检查是否有该模块的缓存
2.如果有,则使用缓存
3.如果没有,则执行该模块代码,并缓存
1.检查该模块是否引入过?
2.是,暂时认该模块为{}
3.否,进入该模块并执行其代码(不做缓存)
import 会被提升到最先执行

commonJS

  1. // mod.js
  2. let conout =1;
  3. let friends =['晓明'];
  4. function plusCount(){
  5. count++;
  6. };
  7. funciton plusYuanhua(){
  8. friendes.push('袁华')
  9. };
  10. setInterval(()=>{
  11. console.log('mod.js 每秒打印 - count',count)
  12. console.log('mod.js 每秒打印 - friends',friends)
  13. },1000)
  14. module.exports ={
  15. coount,
  16. friends,
  17. plusCount,
  18. plusYuanhua
  19. }
  20. ==============================================================================================
  21. //index.js
  22. const mod =require('./mod.js');
  23. console.log('index.js 初次引入 -mod.count',mod.count);
  24. console.log('index.js 初始导入 - mod.friends',mod.friends);
  25. mod.plusCount();
  26. mod.plusYuanhua();
  27. console.log('index.js 执行mod.plusCount 后-mod.count',mod.count);
  28. console.log('index.js 执行mod.plusYuanhua后- mod.friends',mod.friends);
  29. setTimeout(()=>{
  30. //count是基础数据类型,值传递,不共享 ,所以在indx.js改变了 count 并不会改变mod.js 的count
  31. mod.count=3;
  32. console.log('index.js 延迟2s- mod.count',mod.count);
  33. console.log('index.js 延迟2s- mod.friends',mod.friends);
  34. },2000)
  35. /*
  36. index.js 初次导入 - mod.count 1
  37. index.js 初次导入 - mod.friends [ '夏洛' ]
  38. index.js 执行 mod.plusCount/plusYuanhua 后 - mod.count 1
  39. index.js 执行 mod.plusCount/plusYuanhua 后 - mod.friends [ '夏洛', '袁华' ]
  40. mod.js 每秒打印 - count 2
  41. mod.js 每秒打印 - friends [ '夏洛', '袁华' ]
  42. mod.js 每秒打印 - count 2
  43. mod.js 每秒打印 - friends [ '夏洛', '袁华' ]
  44. index.js 延时2s - mod.count 3
  45. index.js 延时2s - mod.friends [ '夏洛', '袁华' ]
  46. mod.js 每秒打印 - count 2
  47. mod.js 每秒打印 - friends [ '夏洛', '袁华' ]
  48. */

ES Module

Node 13.2 增加了对ES Module 的支持,为了使node识别ES Module ,你需要做如下之一
1.更改.js 为.mjs,并使用 node index.mjs
2.package.json 添加字段 ‘type’:’module’,如此所有.js 均被识别为ES Module

  1. // indes.mjs
  2. import { counter} from './mod.mjs';
  3. //1.只读导入,动态读取
  4. //2.不可再外部修改引用,但是可以调用引用包含的方法
  5. counter ={} ;// TypeError: Assignment to constant variable.
  6. console.log('a.js-1',counter)
  7. //mod.mjs
  8. export let counter ={
  9. count:1
  10. }
  11. setInterval(()=>{
  12. console.log('modb.js-1',counter.count)
  13. },1000)

可见 import 为只读引入,如此,mod.mjs 中 count 变化会及时的反应在 index.mjs 中

commoJS

  1. //index.js
  2. let a = require('./modA.js');
  3. let b =require('./modB.js');
  4. console.log('index.js-1','执行完毕',a.done,b.done);
  5. // modA.js
  6. exports.done =false;
  7. let b = require('./mobB.js');
  8. consle.log('modA.js-1',b.done);
  9. exports.done =true;
  10. console.log('modB.js-2','执行完毕');
  11. //modB.js
  12. exports.done =false;
  13. let a =require('./modA.js');
  14. console.log('modB.js-1',a.done);
  15. exports.done=true;
  16. console.log('mobB.js-2','执行完毕')
  17. /*
  18. modB.js-1 false
  19. modB.js-2 执行完毕
  20. modA.js-1 true
  21. modB.js-2 执行完毕
  22. index.js-1 执行完毕 true true
  23. */

执行顺序是这样的:

  1. node 执行 index.js 文件,发现require(‘./modA.js’),暂停 index.js 代码执行,进入 modA 模块
  2. 在 modA 中发现require(‘./modB.js’),暂停 modA 代码执行,将已执行的部分 modA 代码缓存,随后进入 modB 模块
  3. 在 modB 中发现require(‘./modA.js’),提取已缓存的部分 modA,执行所有的 modB 代码,完毕后,缓存 modB 执行结果,执行栈返回至 modA
  4. 执行 modA 剩余代码,完毕后,缓存 modA,执行栈返回 index.js
  5. 在 index.js 发现require(‘./modBjs’),提取已有的 modB 缓存,执行剩余代码

    ES Module

    ```javascript // index.mjs console.log(“before import mod”) import { b } from “./mod.mjs” console.log(“b is “ + b) export let a = b + 1;

// mod.mjs console.log(“before import index”) import { b } from “./index.mjs” console.log(“b is “ + b) export let a = b + 1;

/ before import a a is undefined before import b b is NAN / ```

  1. 进入 index.mjs ,提升 import(‘./modB.mjs’) 语句至顶部,最先执行,进入 modB
  2. 提升提升 import(‘./index.mjs’) 语句至顶部,发现已经执行过 index.mjs,此处将从 index 导入的内容当作 { },执行剩余代码。完毕后,执行栈返回 index.mjs
  3. 执行剩余代码