从原理去理解JS的模块化

125 阅读3分钟

js的模块化

是什么?

模块化就是把程序划分为一个个小结构

在结构中编写袭击的代码,有自己的作用域,不会影响其他结构

并且这个结构可以暴露出去变量、函数、对象等

其他结构可以导入


结构 == 模块,按这种结构划分的开发程序的过程,叫做模块化开发

为什么要有模块化?

随着js能做的事越来越多,开发所需

怎么做?

no-module

图片.png

都引入到index.html中,没有模块概念,定义的变量都是全局变量,会互相造成污染

  • 解决:自执行函数,但是这种方式存在弊端
var moduleBar = (function(){
    var name = "wwh"
    var age = "21"
    
    return {
        name,
        age
    }
})()

commonJS和node

commonJS是一个规范,最开始不是在浏览器使用的

node中,每个文件是一个单独的模块

  • export 和 module.export
  • require

图片.png bar.js

var name = "wwh"
var age = 21
function eat(){
    console.log("eat")
}

export.name = name
export.age = age
export.eat = eat

main.js 入口文件,导入其他模块导出的东西

const bar = require("./bar)
console.log(bar.name)

每个模块,都有一个export空对象,export相当于一个对象 node中实现commonJS的本质就是引用复制

为什么又有module.export?

解答:commonJS是没有module.export,为了实现模块导出,node使用module类,每个模块都是一个module的实例

module是个类 module.export相当于把上面说的那个export对象作为module的一个属性

说不清,还是画个图吧

图片.png

本质上是module.export在导出

module.exports = {}

图片.png

export的意义只是因为commonJS要求有一个export作为导出,node完全可以没有这个

require补充

require查找规则

  • 查查是不是核心模块

  • 是不是以../之类的开头,就说明是本地文件,如果不加后缀,会按照.js/.json/.node顺序来查找。如果没有对应的文件,会把那个作为一个目录,查找下面的index.xxx,再没有,就报错了

  • 没有路径,也不是核心模块,会一层一层在node_modules中找

加载过程

加载过程是同步的

  • 模块首次被引入,会执行一次
  • 多次引入会缓存
  • 循环引用(深度优先) 图片.png

commonJS通过module.export导出的是一个对象

意味着可以将这个对象的引用在其他模块中赋值给其他变量

浅拷贝也就是

AMD/CMD

ES Module

CommonJS,AMD,CMD都是社区规范

ES Module和CommonJS的不同

  • ES Module使用了import和export关键字
  • ES Module使用了编译期静态分析,动态引入

导出

const name = "wwh"
const age = 21

//type1:直接在前面加export
export xxx

//type2:大括号,这个东西不是对象
//这个大括号是要方变量的引用列表
export {
    name
}

//别名
export {
    name as myname
}

导入

//这个大括号不是对象
//.js必须加
import { name, age } from "./xxx/xx.js"

//2别名
import { name as myname, age } from "./xxx/xx.js"

//3*,本质上把一大堆放入foo
import * as foo from "./xxx/xx.js"

export和import结合


export { name, age } from "./xxx.js"

为什么?

图片.png

默认导出default用法

一个模块里只能有一个

import()函数和import关键字区别

为了解决,指定条件下才加载某个模块,也就是import放在运行时

返回一个promise

import("./xxx/xxx.js").then().catch()

ES Module加载过程

  • 解析时加载,不能和运行时代码混在一起
  • 是异步的

图片.png

答案是最后输出aaa,原因是导出的是变量的引用

原理

图片.png