一、commonjs
commonjs是作用于服务端应用程序,让js程序具有模块化功能的一种语法规范,执行方式是同步且运行时加载。
(一)、module.exports 导出
定义一个匿名对象,将需要导出的成员赋值到这个匿名对象上,然后再赋值到module.exports 导出
let name='ommonjs'
let sayhi=()=>{
console.log(str)
}
module.exports={
name,sayhi
}
(二)、exports 导出
exports在每个模块中扮演着一个对象,如同每次在模块中默认执行了let exports = module.exports,那么exports如何使用导出功能呢,只要在exports对象上声明一个要导出去的属性名,将要导出的值赋值进去,但不能直接赋值给exports对象,否则就和module.exports没有关系,例如:exports=function fn() {},导入时拿到的是一个undefind
exports.name='commonjs'
exports.age=10
(三)、require 导入
导入得到是一个对象,对象里面是导出模块所导出的成员,也可以同解构的方式按需导入
const obj=require('./common')
console.log(obj) // {str:'hello',sayhi() fn }
console.log(obj.name) //'commonjs'
总结
exports是引用 module.exports的值。exports 被改变的时候,module.exports不会被改变,而模块导出的时候,真正导出的执行是module.exports,而不是exports。
最后,关于exports和module.exports的关系可以总结为:
- module.exports 初始值为一个空对象 {},所以 exports 初始值也是 {};
- exports 是指向的 module.exports 的引用;
- require() 返回的是 module.exports 而不是 exports;
二、ES6模块化
ES6模块化也是和commonjs一样是具有将js模块化功能的语法规范,不过只能用于在能识别ES6语法浏览器环境。
ES6的模块暴露和引入可以让我们实现模块化编程,export或export default暴露,import引入变量。ES6一共有3中模块暴露方法。
(一)、多行暴露:
在模块1:module1.js中
//多行暴露
export function foo() {
console,console.log('foo() moudle1');
}export function bar() {
console.log('bar() moudle1')
}
(二)、统一暴露:
在模块2:module2.js中
function fun1() {
console.log('fun1() module2')
}function fun2() {
console.log('fun2() module2')
}
// 统一暴露
export {
fun1,fun2}
注意:以上两种向外暴露方式在主文件引入时必须使用对象的解构赋值引用(不能使用变量接收的方式来引入)
在主模块:main.js中
import {
foo,bar} from '.js/src/module1.js'
import {
fun1,fun2} from './js/src/module2.js'
(三)、默认暴露:
在模块3:module3.js中
export default {
foo() {
console.log('默认暴露方式')},bar() {
console.log('默认暴露')}
}
注意:默认暴露的方式只允许有一个: export default {},且在主模块引入时可以使用定义变量来接收的方式!
// 引入模块3
import module3 from '.js/src/module3.js'// 使用模块
module3.foo()
module3.bar()
总结:
- 在一个文件或模块中,export、import可以有多个,export default仅有一个
- 通过export方式导出,在导入时要加{ },export default则不需要
三、commonjs与es6模块化直接的差别
- commonjs导出是值的拷贝;es6模块化是导出的值的引用
- commonjs加载是运行时加载;而es6模块化是编译时加载,会比commonjs更加高效。(CommonJS加载的是一个对象(module.exports属性),该对象只有在脚本运行完才会生成,而ES6模块不是对象,他的对外接口是一种静态定义,在代码静态解析阶段就会完成)