这是我参与「第五届青训营 」笔记创作活动的第3天。
一、重点内容
- commonJS认识与基本使用
- ES Module认识与基本使用
二、详细内容介绍
CommonJS
在Node当中每个js文件都是单独的模块,互相应用需要导入导出。
node可以实现commonJS。(CJS是一个规范)
导入require
function myFunc(){
console.log("lalala")
}
exports.myFunc=myFunc
导出exports(exports是一个对象)
const duixiang=require(./02yinru.js)
duixiang.myFunc()
duixiang.myFunc2()
导入对象后,可以进行解构,这样就不用每次都有个"对象."在前面
const{myFunc,myFunc2}=require(./02yinru.js)
myFunc()
myFunc2()
实质
commonJS在node中实现的本质:
- exports和require指向的是一个地方(引用赋值),所以exports的内容改变的话require的内容也改变,反之亦成立,(但一般不会让导入者修改,此处只是说commonjs里可以这样)。
- 也可以使用module对象的exports属性,和上面的方法效果以及exports指向的地方一样。
- Node导出的本质是在导出module.exports对象
module.exports.myFunc=myFunc
//exports===module.exports
exports
开发中常见的写法为:
module.exports{
//一旦有花括号就是创建新的内存,因此和之前exports.name=name创建的内存不是同一块,不要再用前者了
myFunc,
myFunc2
}
两个都有存在是因为:
commonJS先就有exports,而Node中使用Module的类来实现模块的导出,每个模块都是Module的一个实例,也就是module。因此折中让module.exports与exports都能用。
require
require(X)X是内置模块,例如path,http,html。
不加后缀名,默认先找.js再找.json再找.node,都没有,将X当作目录,找下面的index.js/.json/.node
Node模块的加载过程
- 同一个模块被多次引入时,会缓存,最终只加载(运行)一次。因为每个模块对象module都有一个属性:loaded,为false表示未加载,为true表示已加载。
- 如果有循环引入,Node采用深度优先。
CommonJS加载模块是同步的,在服务器由于加载的js都是本地文件,很快,没什么问题,但应用到浏览器就一般不用这个规范了,因为慢。要用异步例如AMD规范、CMD规范。(利用webpack打包是另一个情况,打包之后无所谓)
ES Module
ES Module
ESMA自己推出的模块化规范。
- 使用import和export关键字。
- 采用编译期的静态分析,并且也加入了动态引用的方式。
- 采用ES Module 自动采用严格模式。
导入导出
const name ="hihihi"
const age="18"
function sayhello(){
console.log("hello~")
}
export{
name,
age,
sayhello
}
import{name as fname,age,sayhello}from "./foo.js"
console.log(fname)
console.log(age)
sayhello()
import和export结合简便写法:
export{name,age,sayhello}from "./foo.js"
避免命名冲突:
- import{name as fname,age as fage,sayhello}from "./foo.js" 在导入时单独起别名。
- import *as foo from "./foo.js"在导入时给整个模块起一个别名。
import函数(异步的)
因为ES Module在被JS引擎解析时,就要知道依赖关系,所以通过import加载一个模块,是不可以放到逻辑代码中的,要放在顶部。如果是要满足某个条件才加载的话,就可以使用import函数。
let flag=true
if(flag){
const importPromise=import("./foo.js")//import函数返回的是一个promise
importPromise.then(res=>{
console.log(res.name,res.age)
})
}
三、课后总结
学习工具的使用的时候或是某些规范的时候,虽然直接学习最常用的一种用法就可以,但是如果稍微往深处多了解一下版本的迭代以及实现的逻辑,会更有收获一些。这次笔记书面整理的内容不多,主要是自己在运行进行理解和实际的对比。