一.前端模块化的进化过程
- 全局function模式 缺陷:容易引发全局命名空间冲突
var a = 1
function add() {
a++
}
function api() {
return {
name: 'lw',
age: 18
}
}
- 全局namespace模式 缺陷:外部能够修改模块内部数据
var __Module = {
a: 1,
add() {
a++
},
api() {
return {
name: 'lw',
age: 18
}
}
}
//__Module.a = 100
- IIFE模式(自执行函数)缺陷:无法解决模块间相互依赖问题
(function(global) {
var a = 1
function add() {
a++
}
function geta() {
return a
}
function seta(x) {
a = x
}
function api() {
return {
name: 'lw',
age: 18
}
}
global.__Module = {
a,
geta,
seta,
add,
api
}
}(window))
//注意__Module.a只是值引用 __Module.a =100 函数内部变量不会改变的
4.IIFE模式增强 缺点:多依赖传入时,代码阅读困难 无法支持大规模的模块化开发 无特定语法支持,代码简陋
//module1
(function(global) {
var a = 1
function add() {
a++
}
function geta() {
return a
}
function seta(x) {
a = x
}
function api() {
return {
name: 'lw',
age: 18
}
}
global.__Module1 = {
a,
geta,
seta,
add,
api
}
}(window))
//module2
(function(global,module){
function log() {
}
global.__Module2 = {
log,
api:module.api
}
}(window,__Module1))
//注意要先引用module1
二.commonJS规范
- 特点
1.在 commonjs 中每一个 js 文件都是一个单独的模块,我们可以称之为 module;
2.该模块中,包含 CommonJS 规范的核心变量: exports、module.exports、require;
3.exports 和 module.exports 可以负责对模块中的内容进行导出;
4.require 函数可以帮助我们导入其他模块(自定义模块、系统模块、第三方库模块)中的内容;
2.原理
每个模块文件上存在 module,exports,require三个变量
module 记录当前模块信息。
require 引入模块的方法。
exports 当前模块导出的属性
这三个变量是没有被定义的,但是我们可以在 Commonjs 规范下每一个 js 模块上直接使用它们。在 nodejs 中还存在 __filename 和 __dirname 变量
在编译的过程中,实际 Commonjs 对 js 的代码块进行了首尾包装,使用的 require ,exports ,module 是通过形参的方式传递到包装函数中的, fn_handle.js中被包装之后的样子如下:
(function(exports,require,module,__filename,__dirname){
const setName = require('./fn_data.js')
module.exports = function set(){
return {
name: setName(),
title: '夜空中最亮的星'
}
}
})
包装函数(后面用eval执行)
function wrapper (script) {
return '(function (exports, require, module, __filename, __dirname) {' +
script +
'\n})'
}
三.AMD和CMD和UMD规范
- amd和cmd都是异步加载js(执行代码发现依赖然后去加载js)
- amd是依赖前置(加在完不存在依赖或者依赖执行完就执行)cmd(加载完也不执行,根据入口模块的代码执行顺序执行) //这里的执行是执行回调
- umd就是node+amd webpack一般默认打包就是这种格式(就是代码里兼容判断环境是node还是浏览器选择用那种格式)