前端发展史
所有功能的出现都是为了解决一个相对应的问题。
在前端发展的浩荡时间里,随着浏览器和电脑设备的发展,前端项目越来越复杂,项目目录越来越大,出现了各种JS文件,但是在各个JS文件引用之间,总是有可能出现函数声明重名或变量声明重名。因此为了解决这个问题,相应提出了解决方案:前端模块化。

一,闭包,立即执行函数(IIFE)实现前端模块化
在最一开始大家只是用闭包的方式来实现前端模块化,在闭包将函数中声明和实现,封装在_Module对象中,再挂载在全局作用域(window或global)身上,来基本实现前端的模块化。
let global = (function () {
return globalThis || window || global;
})();
(function (global) {
let x = 1;
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
return (global._Module = {
x,
add,
subtract,
});
})(global);
global._Module.x = 2;
console.log(global._Module.x);
二,CommonJS标准
在这前端发展举步维艰的时刻,CommonJS标准应运而生
node实现了commonJS:
(1),介绍
Node 应用由模块组成,采用 CommonJS 模块规范。每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。
(2),api
- 暴露模块:module.exports = value或exports.xxx = value
- 引入模块:require(xxx),如果是第三方模块,xxx为模块名;如果是自定义模块,xxx为模块文件路径
使用module.exports 导出module2.js文件想要暴露的方法和属性
// module2.js
let SayName = function (Person) {
console.log("Hello, my name is " + Person.name);
};
let SayAge = function (Person) {
console.log("I am " + Person.age + " years old");
};
let SayCity = function (Person) {
console.log("I live in " + Person.city);
};
module.exports = { SayName, SayAge, SayCity };
使用require引入别module2.js导出的方法
// module1.js
let { SayAge, SayName, SayCity } = require("./module2.js");
let Person = {
name: "John",
age: 30,
city: "New York",
};
SayCity(Person);
SayAge(Person);
(3),特点
- 所有代码都运行在模块作用域,不会污染全局作用域。
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 模块加载的顺序,按照其在代码中出现的顺序。
三,AMD和CMD规范
AMD
Asynchronous Module Definition,中文名是异步模块定义的意思。它是一个在浏览器端模块化开发的规范。requireJS实现了这个规范
CMD
SeaJS 在推广过程中对模块定义的规范化产出(国产)。
总结:
不过随着ES6的出现,这两个规范也逐渐不再使用。一些比较老一点的项目还可能在使用这两个
ES6 规范
(1),介绍
在2016年 Ecm提出了ES6规范,在ES6规范中实现了前端的模块化,
(2),api
- import aaa , { bbb , ccc } from ‘’ ./xxx "
aaa:是export default一个文件只能导出一个
bbb,ccc:是正常 export导出
xxx:是引用的文件夹目录
到处方式有很多种:
- export let aaa = [ function(){} || value]
- export aaa
- export default aaa;
// module2.js
export let add = function (a, b) {
return a + b;
};
export let subtract = function (a, b) {
return a - b;
};
const log = function (a) {
console.log(a);
};
export default log;
在浏览器中使用 type=“module” 引入其他文件注意:
- 必须加上type=“module”,这样浏览器才会将该使用ES6去执行,否则默认是传统脚本
- module是默认不支持同源加载的,需要启动一个服务器,解决跨域问题
// index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script type="module">
import log, { add, subtract } from "./module2.js";
console.log(add(1, 2));
console.log(subtract(1, 2));
log(1);
</script>
</body>
</html>
(3),特点
ES6模块中的值属于【动态只读引用】。
- 对于只读来说,即不允许修改引入变量的值,import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
- 对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。
- 循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。
&spm=1001.2101.3001.5002&articleId=145570489&d=1&t=3&u=523d6a0d2abd46e5a45a85a47d40a249)
449

被折叠的 条评论
为什么被折叠?



