前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >是export还是module.exports,是import还是require,是ES6还是CommonJS,是爱❤️还是责任?

是export还是module.exports,是import还是require,是ES6还是CommonJS,是爱❤️还是责任?

作者头像
前端小哥哥
发布2023-05-04 19:48:03
2110
发布2023-05-04 19:48:03
举报
文章被收录于专栏:前端小哥哥前端小哥哥

故事要从一次错误的编码开始。。。

Node的模块

众所周知,在上古年代,node的开发一直被 Commonjs 规范所支配着,这也是悲剧发生的导火索,请看灾难现场:

代码语言:javascript
复制
// version.js
var version = 3;
function incVersion() {
  version++;
}
module.exports = {
  version,
  incVersion,
};

// main.js
var mod = require('./version');
console.log(mod.version);  // 3
mod.incVersion();
console.log(mod.version); // 3

这,这一瞬间,时间的涡轮好像停止了一样,版本号变量version一直停留在3永不向前,就好像我的人生那样,停滞不前,是命运的捉弄,还是人为的操控呢?

不,是值的拷贝,CommonJS 模块输出的是值的拷贝,也就是说,mod.version是一个原始类型的值,会被缓存,那么我们怎样解决这个问题呢?

代码语言:javascript
复制
# 可以改写成函数
var version = 3;
function incVersion() {
  version++;
}
module.exports = {
  get version() {
    return version
  },
  incVersion,
};

或者用es6的import引用,那么这又是什么呢,敲黑板,画重点,要考。

ES6 模块与 CommonJS 模块

它们有两个重大差异。

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

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

CommonJS

ES6

特征

exports

x

是 module.exports 的一个引用

module.exports

x

module.exports = xxx,就是导出xxx

export

x

多个

export default

x

单个

require

导出的内容是module.exports的指向的内存块内容/ es6时是一个对象({default:xxx})

import

x

引用多个

代码语言:javascript
复制
//无聊的冷门尝试 es6试用require
//a.js
export default 123
//main.js
const a = require('./a')
console.log('a', a) //{default: 123}

//a.js
export const a = 123
//main.js
const a = require('./a')
console.log('a', a) //{a: 123}

exports 和 module.exports

在一个node执行一个文件时,会给这个文件内生成一个 exports和module对象, 而module又有一个exports属性。他们之间的关系如下图,都指向一块{}内存区域。

代码语言:javascript
复制
exports = module.exports = {};

export 和 export default

首先我们讲这两个导出,下面我们讲讲它们的区别

  1. export与export default均可用于导出常量、函数、文件、模块等
  2. 在一个文件或模块中,export、import可以有多个,export default仅有一个
  3. 通过export方式导出,在导入时要加{},export default则不需要
  4. export能直接导出变量表达式,export default不行。

天坑-循环依赖

“循环依赖”(circular dependency)指的是,a脚本的执行依赖b脚本,而b脚本的执行又依赖a脚本。

代码语言:javascript
复制
// a.js
var b = require('b'); //a-step 1
module.exports.value = 'a'; //a-step 2

// b.js
var a = require('a'); //b-step 1
module.exports.value = 'b'; //b-step 2

一般很少会这样写,出现的话证明你的功能逻辑有耦合了,应该先分开,但是一些大型项目就很难避免,小弟不才,真的遇到过。

node的执行顺序

a-step 1 –> b-step 1 –> b-step 2 –> a-step 2

当年的黑科技临时解决办法,其实不建议,就是将a中的a-step 2移到a-step 1之上。

代码语言:javascript
复制
 // a.js
module.exports.value = 'a'; //a-step 2
var b = require('b'); //a-step 1

上面的其实是Commonjs版的,es6的解决方法有点不一样,具体就是将要引用的变量改成函数,因为函数具有提升作用,在加载时就已经有定义了。(ps:改成了函数表达式也不行,因为不具有提升作用)

最后

那么在座各位天才小儿童,肯定能想到怎样用es6解决那个灾难现场了吧,答案就是直接用

代码语言:javascript
复制
//a.js
var version = 3;
function incVersion() {
  version ++;
}
export { version, incVersion }

//main.js
import { version, incVersion } from './a'
console.log( 'version', version )
incVersion()
console.log( 'version', version )
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Node的模块
  • ES6 模块与 CommonJS 模块
    • exports 和 module.exports
      • export 和 export default
      • 天坑-循环依赖
      • 最后
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档