前端开发学习之【模块化】
1.模块化介绍
编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。将一个复杂程序依据一定规则封装成几个块,并进行组合在一起;块的内部数据和实现是私有的,只是向外部暴露一些接口和方法。
把代码进行模块化拆分的好处:
- 提高了代码的复用性
- 提高了代码的可维护性
- 可以实现按需加载
- 避免命名冲突
2.CommonJS
CommonJS详解
特点说明:
- 每一个 JavaScript 文件就是一个独立模块,其作用域仅在模块内,不会污染全局作用域。
- 在服务器端加载同步(可能会阻塞),按编写顺序加载;
- 在浏览器端需要提取编译打包处理;
- 模块可以加载多次,但只会在第一次加载时运行一次,然后运行结果就会被缓存起来。下次再加载是直接读取缓存结果。模块缓存是可以被清除的。
基本语法:
暴露模块:暴露的本质是exports对象
module.exports=value
exports.xxx=value
- module.exports 是真正决定导出对象的【重要角色】
- exports 仅仅是 module.exports 的【一个引用】
- 赋值给 module.exports 必须立即完成,不能在任何回调中完成(应在同步任务中完成)。
- 当 module.exports 属性被新对象完全替换时,通常也会“自动”重新分配 exports,如果使用 exports 变量导出新对象,则必须“手动”关联 module.exprots 和 exports,否则无法按预期输出模块值。
CommonJS 规定:
① 每个模块内部,module 变量代表当前模块。
② module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
③ 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。
module.exports={msg:'m1',foo(){ }
}
exports.foo=function(){}
exports.arr=[1,2,4]
引入模块:自定义模块xxx为文件路径;第三方模块xxx为模块名
require(xxx)
let m1=require('../m1')m1.foo();
let m2=require('../m2')
m2.foo();
实现:
- 服务器端:Node.js
- 浏览器端:Browserify
每个模块内部,都有一个 module 对象,表示当前模块;module模块存储了和当前模块有关的信息;外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象。
// Module 构造函数
function Module(id = '', parent) {this.id = idthis.path = path.dirname(id)this.exports = {}moduleParentCache.set(this, parent)updateChildren(parent, this, false)this.filename = nullthis.loaded = falsethis.children = []
}
模块加载机制:
- 优先从缓存中加载:模块在第一次加载后会被缓存。 这也意味着多次调用 require() 不会导致模块的代码被执行多次。
- 内置模块是由 Node.js 官方提供的模块,内置模块的加载优先级最高。
- 使用 require() 加载自定义模块时,必须指定以 ./ 或 …/ 开头的路径标识符。
- 如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ‘./’ 或 ‘…/’ 开头,则 Node.js 会从当前模块的父 目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
3.ES6
依赖模块需要编译打包处理
分别暴露:
export function foo() {console.log('foo()');
}export function bar() {console.log('bar()');
}export let arr = [1, 2, 3, 4, 5]
统一暴露:
function fun() {console.log('fun()');
}function fun2() {console.log('fun2()');
}export { fun, fun2 }
默认暴露:
一个模块只能有一个默认导出,对于默认导出,导入的名称可以和导出的名称不一致。
export default {msg: 'hello......',fun: () => {console.log('aaaaaaaaaaaaa');}
}
引入:
// 引入其他的模块
// 如果是单个的js文件 引入时要加上后缀
// 引入的是一个npm下载的包,就不需要加后缀
import {foo, bar} from './module1.js'
import {fun, fun2} from './module2.js'
import module3 from './module3.js'
import $ from 'jquery'
import express from 'express'
重命名:
import {fun as fun1} from 'fun.js'
AMD与CMD
前端开发学习之【模块化】
1.模块化介绍
编程领域中的模块化,就是遵守固定的规则,把一个大文件拆成独立并互相依赖的多个小模块。将一个复杂程序依据一定规则封装成几个块,并进行组合在一起;块的内部数据和实现是私有的,只是向外部暴露一些接口和方法。
把代码进行模块化拆分的好处:
- 提高了代码的复用性
- 提高了代码的可维护性
- 可以实现按需加载
- 避免命名冲突
2.CommonJS
CommonJS详解
特点说明:
- 每一个 JavaScript 文件就是一个独立模块,其作用域仅在模块内,不会污染全局作用域。
- 在服务器端加载同步(可能会阻塞),按编写顺序加载;
- 在浏览器端需要提取编译打包处理;
- 模块可以加载多次,但只会在第一次加载时运行一次,然后运行结果就会被缓存起来。下次再加载是直接读取缓存结果。模块缓存是可以被清除的。
基本语法:
暴露模块:暴露的本质是exports对象
module.exports=value
exports.xxx=value
- module.exports 是真正决定导出对象的【重要角色】
- exports 仅仅是 module.exports 的【一个引用】
- 赋值给 module.exports 必须立即完成,不能在任何回调中完成(应在同步任务中完成)。
- 当 module.exports 属性被新对象完全替换时,通常也会“自动”重新分配 exports,如果使用 exports 变量导出新对象,则必须“手动”关联 module.exprots 和 exports,否则无法按预期输出模块值。
CommonJS 规定:
① 每个模块内部,module 变量代表当前模块。
② module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
③ 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。
module.exports={msg:'m1',foo(){ }
}
exports.foo=function(){}
exports.arr=[1,2,4]
引入模块:自定义模块xxx为文件路径;第三方模块xxx为模块名
require(xxx)
let m1=require('../m1')m1.foo();
let m2=require('../m2')
m2.foo();
实现:
- 服务器端:Node.js
- 浏览器端:Browserify
每个模块内部,都有一个 module 对象,表示当前模块;module模块存储了和当前模块有关的信息;外界用 require() 方法导入自定义模块时,得到的就是 module.exports 所指向的对象。
// Module 构造函数
function Module(id = '', parent) {this.id = idthis.path = path.dirname(id)this.exports = {}moduleParentCache.set(this, parent)updateChildren(parent, this, false)this.filename = nullthis.loaded = falsethis.children = []
}
模块加载机制:
- 优先从缓存中加载:模块在第一次加载后会被缓存。 这也意味着多次调用 require() 不会导致模块的代码被执行多次。
- 内置模块是由 Node.js 官方提供的模块,内置模块的加载优先级最高。
- 使用 require() 加载自定义模块时,必须指定以 ./ 或 …/ 开头的路径标识符。
- 如果传递给 require() 的模块标识符不是一个内置模块,也没有以 ‘./’ 或 ‘…/’ 开头,则 Node.js 会从当前模块的父 目录开始,尝试从 /node_modules 文件夹中加载第三方模块。
3.ES6
依赖模块需要编译打包处理
分别暴露:
export function foo() {console.log('foo()');
}export function bar() {console.log('bar()');
}export let arr = [1, 2, 3, 4, 5]
统一暴露:
function fun() {console.log('fun()');
}function fun2() {console.log('fun2()');
}export { fun, fun2 }
默认暴露:
一个模块只能有一个默认导出,对于默认导出,导入的名称可以和导出的名称不一致。
export default {msg: 'hello......',fun: () => {console.log('aaaaaaaaaaaaa');}
}
引入:
// 引入其他的模块
// 如果是单个的js文件 引入时要加上后缀
// 引入的是一个npm下载的包,就不需要加后缀
import {foo, bar} from './module1.js'
import {fun, fun2} from './module2.js'
import module3 from './module3.js'
import $ from 'jquery'
import express from 'express'
重命名:
import {fun as fun1} from 'fun.js'