js的模块化
是什么?
模块化就是把程序划分为一个个小结构
在结构中编写袭击的代码,有自己的作用域,不会影响其他结构
并且这个结构可以暴露出去变量、函数、对象等
其他结构可以导入
结构 == 模块,按这种结构划分的开发程序的过程,叫做模块化开发
为什么要有模块化?
随着js能做的事越来越多,开发所需
怎么做?
no-module
都引入到index.html中,没有模块概念,定义的变量都是全局变量,会互相造成污染
- 解决:自执行函数,但是这种方式存在弊端
var moduleBar = (function(){
var name = "wwh"
var age = "21"
return {
name,
age
}
})()
commonJS和node
commonJS是一个规范,最开始不是在浏览器使用的
node中,每个文件是一个单独的模块
- export 和 module.export
- require
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的一个属性
说不清,还是画个图吧
本质上是module.export在导出
module.exports = {}
export的意义只是因为commonJS要求有一个export作为导出,node完全可以没有这个
require补充
require查找规则
-
查查是不是核心模块
-
是不是以../之类的开头,就说明是本地文件,如果不加后缀,会按照.js/.json/.node顺序来查找。如果没有对应的文件,会把那个作为一个目录,查找下面的index.xxx,再没有,就报错了
-
没有路径,也不是核心模块,会一层一层在node_modules中找
加载过程
加载过程是同步的
- 模块首次被引入,会执行一次
- 多次引入会缓存
- 循环引用(深度优先)
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"
为什么?
默认导出default用法
一个模块里只能有一个
import()函数和import关键字区别
为了解决,指定条件下才加载某个模块,也就是import放在运行时
返回一个promise
import("./xxx/xxx.js").then().catch()
ES Module加载过程
- 解析时加载,不能和运行时代码混在一起
- 是异步的
答案是最后输出aaa,原因是导出的是变量的引用
原理