commonjs模块和ES6模块引入文件区别

2,927 阅读3分钟

1.前言

commonjs中使用module.exports,exports和require组合来实现文件的引入,ES6模块则使用export和import来实现,那他们究竟有什么区别,我们就来一起讨论一下。

2.具体区别

commonjs和ES6

  1. CommonJS模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。commonjs是基于node环境中运行的,使用require来加载模块的时候是同步的,也就是说只有等第一个模块加载完成后,才会加载第二个,在服务器中加载本地文件是很快的,只需要到相应的位置去读区就行,而在浏览器中,则会收到网速等因素的影响,可能会使浏览器出现假死的情况,显然是不太合适的。
  2. CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。 commonjs在第一次加载时运行了一次,由于它输出的是一个值的拷贝,我们暂时理解成一个对象,下面会做说明,第一次加载时会生成这个对象,并且缓存起来,之后require相同的模块则不会再进行加载,而是从缓存的对象中取出。
const data=require(./content.js)

//从content中取出一个经过拷贝的对象,命名为data。

ES6则输出一个路径,在import的时候在对应的路径下只取出我们需要的值,defaut的情况下面会做说明。

import {name,age,six} from './content.js'

//编译时只取出我们需要的

module.exports,exports和export

在CommonJs中,规定用module来表示当前的模版,exports来表示模版输出的接口,所以才有了module.exports的形式,我们只需要给exports属性赋值,不需要对值进行命名。require时引入所有module对象下的exports属性下的所有值。

//content.js
module.exports={
       name:'zhangsan',
       age:'18',
       six:'nan'
}
//index.js
const data = require(./content.js)
console.log(data.name)
//一次性全部引入整个对象,部分消费

我们可以这么理解,默认modole.exports={},这个指向是不能改变的。

module.exports=const data=1 //错误写法,改变了modole.exports的指向
module.exports.data=1 //正确写法,

exports可以看做成modole.exports的指向。

let module={
    exports:{}
}
let exports=module.exports //此时exports和modole.exports指向同一路径
console.log(exports===module.exports) //true
   // exports在不改变指向的情况下是可以改变module.exports中的值,为了产生不必要的麻烦,最好都使用module.exports

在ES6中,由于要做到动态引入,所以输出的对象应该是一个个单独的对象,而不是整个所有对象的集合。因此,export 需要和模块内的变量建立对应关系。

//content.js
export const name='zhangsan'
export const age='18'
export const six='nan'
//index.js
import {name,age} from './content.js'
//动态引入需要的值,

export default 'zhangsan' === export const defalut='zhangsan'
import name from './content.js'
//可以把export default看做成输出一个变量名为default的值,在import引入时,可以自定义default的名字。

import和require

1.import有多种写法。require只有一种

import fs from 'fs'
import {readFile} from 'fs' //从 fs 导入 readFile 模块
import {default as fs} from 'fs' //从 fs 中导入使用 export default 导出的模块
import * as fileSystem from 'fs' //从 fs 导入所有模块,引用对象名为 fileSystem
import {readFile as read} from 'fs' //从 fs 导入 readFile 模块,引用对象名为 read


const data=require(./content.js)

2.import引入的是一个模块的地址,默认是只读的,但是在不改变指向的情况下,可以改变模块里变量的值,所有用到这个值的地方数据都会改变。而require引入的是一个经过拷贝的对象,改变它的值,原模版里的值无法改变。

//index.js
import fs from './content.js'
console.log(fs.name) // 'zhangsan'
fs.name='lisi'
//index2.js
import fs from './content.js'
console.log(fs.name) //'lisi'
//index2.js
import fs from './content.js'
fs.name=funtion add(){} //报错,改变了fs.name的指向了。

3.import命令具有提升效果,可以先使用后加载,require必须先加载才能使用。

console.log(name)

import { name } from './content.js';

以上分享纯属个人理解,如果有问题请大家指出来,本人也在不断的学习和理解中,随时更新文章。

完结!