关于export module.exports import

566 阅读2分钟

我们在使用nodejs时候,经常会用到export、module.exports,我们扪心自问,自己真的了解他们吗?知道内部是怎么实现的吗?

其实不论我们使用他们两个的谁进行导出,其实最后都是调用了 module.exports,这个我们可以通过源码进行窥探,源码中会有这么一步操作,export = module.exports。所以我们在使用export的时候也是能导出的。

那node中为啥还要有export的呢?

node中exports导出的作用:commonJs要求有一个exports作为导出标准,所以node做了妥协,其实node内部帮我们做了赋值操作,module.exports = exports, 所有我们顶上exports.name = ... 才能实现导出功能

ESmodule的导入和导出

导出的三种方式

  • 方式一:单个导出

export const name = '张三';

  • 方式二:整个导出(这个大括号不是对象,放置的是多个变量引用的列表,不是对象)

export { name, age };

  • 方式三:导出时可以给变量设置别名

export { name as FName };

导入的三种方式

  • 方式一: 基础导入

import { name, age } from './bar.js'

  • 方式二:导出设置别名

import { name as wName, age as wAge } from './bar.js'

  • 方式三:全部导出,重设为

import * as foo from './bar.js'

  • 方式四:export 和 import 结合使用,从某一个文件中全部导入后,再统一导出,在自己开发组件库或者工具的时候,可以把所有的接口放置到入口中,统一导出

export { name } from './bar.js'

关于 export 和 import 的原理解析

// 原理解析
/*
  bar.js
  let name = 'why'
  let age  = 'age'

  setTimeout(() => {
    name = 'aaaa'
  }, 1000);

  导出的是name、age的引用,不是对象
  export { name, age }


  index.js
  import { name, age } from './bar.js';

  setTimeout(() => {
    console.log(name)  // 结果是:aaaa
  },  2000)


  原理是当js引擎在解析阶段时候,会创建一个 模块环境记录(module environment record)
  bindings: 实时绑定
  const name = name;
  const age = age;
  这块绑定的都是引用

  所以在index.js中打印的就是最新修改的值 aaaa


  反过来测试
  index.js
  setTimeout(() => {
    name = 'cccc'
  }, 1000)

  bar.js
  setTimeout(() => {
    console.log(name)
  })

  报错 TypeError: Assignment to constant variable,所以可以证明js引擎在定义的时候声明为const,所以不能进行反向修改
  
*/