前端模块化学习|青训营笔记

71 阅读3分钟

这是我参与「第五届青训营 」笔记创作活动的第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中实现的本质:

  1. exports和require指向的是一个地方(引用赋值),所以exports的内容改变的话require的内容也改变,反之亦成立,(但一般不会让导入者修改,此处只是说commonjs里可以这样)。
  2. 也可以使用module对象的exports属性,和上面的方法效果以及exports指向的地方一样。
  3. 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)
})
}

三、课后总结

学习工具的使用的时候或是某些规范的时候,虽然直接学习最常用的一种用法就可以,但是如果稍微往深处多了解一下版本的迭代以及实现的逻辑,会更有收获一些。这次笔记书面整理的内容不多,主要是自己在运行进行理解和实际的对比。