js模块化规范—概念和模块化进化史以及模块化的问题
模块的概念
一个复杂的项目开发中,会写很多js文件,一个js文件执行某些特定的功能,那么每个js都可以称为一个模块,这就是模块的概念
每个js模块内部数据/实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
模块化的进化史
全局function模式:将不同的功能封装成不同的全局函数
问题: Global被污染了, 很容易引起命名冲突
//数据
let data = 'atguigu.com' //操作数据的函数
function foo() {
console.log(`foo() ${data}`)
}
function bar() {
console.log(`bar() ${data}`)
}
let data2 = 'other data';
function foo() { //与另一个模块中的函数冲突了
console.log(`foo() ${data2}`)
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01_全局function模式</title>
</head>
<body>
<script type='text/javascript' src='module1.js'></script>
<script type='text/javascript' src='module2.js'></script>
<script type='text/javascript'>
let data = "修改后的数据" // 模块1中已经定义了data变量,重复定义同名变量报错
foo() // module2模块中的foo()方法覆盖了module1模块中的foo()方法
bar()
</script>
</body>
</html>
namespace模式
简单对象封装,减少了全局变量
问题: 不安全(数据不是私有的, 外部可以直接修改)
let myModule1 = {
data: 'atguigu.com',
foo() {
console.log(`foo() ${this.data}`)
},
bar() {
console.log(`bar() ${this.data}`)
}
}
let myModule2 = {
data: 'atguigu.com2222',
foo() {
console.log(`foo() ${this.data}`)
},
bar() {
console.log(`bar() ${this.data}`)
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02_namespace模式</title>
</head>
<body>
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript">
myModule1.foo() // foo() atguigu.com
myModule1.bar() // bar() atguigu.com myModule2.foo() // foo() atguigu.com2222
myModule2.bar() // bar() atguigu.com2222 myModule1.data = 'other data' //能直接修改模块内部的数据
myModule1.foo() // foo() other data </script>
</body>
</html>
IIFE模式: 匿名函数自调用(闭包)
IIFE : immediately-invoked function expression(立即调用函数表达式)
作用: 数据是私有的, 外部只能通过暴露的方法操作
问题: 如果当前这个模块依赖另一个模块怎么办
(function (window) {
let data = 'atguigu.com' // 数据
//操作数据的函数
function foo() { //用于暴露有函数
console.log(`foo() ${data}`)
}
function bar() {//用于暴露有函数
console.log(`bar() ${data}`)
otherFun() //内部调用
}
function otherFun() { //内部私有的函数
console.log('otherFun()')
}
//暴露行为
window.myModule = {foo, bar}
})(window)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>03_IIFE模式</title>
</head>
<body>
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript">
myModule.foo() // foo() atguigu.com
myModule.bar() // bar() atguigu.com
//myModule.otherFun() //myModule.otherFun is not a function
console.log(myModule.data) //undefined 不能访问模块内部数据
myModule.data = 'xxxx' //不能修改的模块内部的data,这只是给myModule对象增加了一个data属性
myModule.foo() // 没有改变,foo() atguigu.com </script>
</body>
</html>
IIFE模式增强 : 引入依赖
这就是现代模块实现的基石
(function (window, $) {
let data = 'atguigu.com' // 数据
// 操作数据的函数
function foo() { // 用于暴露有函数
console.log(`foo() ${data}`)
$('body').css('background', 'red')
}
function bar() { // 用于暴露有函数
console.log(`bar() ${data}`)
otherFun() // 内部调用
}
function otherFun() { //内部私有的函数
console.log('otherFun()')
}
//暴露行为
window.myModule = {foo, bar}
})(window, jQuery)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04_IIFE模式增强</title>
</head>
<body>
<!--引入的js必须有一定顺序-->
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module4.js"></script>
<script type="text/javascript">
myModule.foo() // foo() atguigu.com
</script>
</body>
</html>
为什么要模块化开发
首先来说明一下,项目中js为什么要模块化的开发,当项目开发越来越复杂的时候,会经常遇到代码冲突,每个js文件之间的依赖关系,当js文件越来越多的时候页面加载性能等等一些问题
代码冲突:比如在团队协作的过程中,同事A写了一个组件库common的一个js文件,里面有个操作选项卡的一个函数叫做tab,然后同事B在同一个页面中进行修改的时候,也定义了一个叫做tab的函数,那这个时候,这两个方法就冲突了(不仅函数冲突,包括变量等等),一般情况下,简单的解决方案就是给这些函数或者变量加上命名空间(这个解决方案的缺点是名字比较长 , 只能降低冲突,不能完全避免)
var above = {}; //名字比较长 , 只能降低冲突,不能完全避免
above.a = 10;
above.tab = function(){};
above.drag = function(){};
above.dialog = function(){};
//调用的时候需要加上前缀,如果命名空间比较长的时候,调用的时候更加麻烦
above.tab();
多个js文件之间的依赖关系:当项目越来越大的时候,项目需要将js进行分层,当a.js和b.js两个文件都需要引入页面中,并且b.js需要依赖a.js的时候,当时后期项目需求更改需要加入一个功能,在写一个c.js文件,需要依赖a.js,当越来越多文件,文件之间有相互依赖的关系,如果少了某个依赖的文件那么页面就出错了
模块化的好处和问题
避免命名冲突(减少命名空间污染),更好的分离, 按需加载,更高复用性,高可维护性
模块化能带来很多好处,但现实开发中也会带来问题

页面引入加载script,产生的问题:请求过多,依赖模糊,难以维护,所以我们需要一些模块化的规范来解决这些问题
SeaJs简介
Seajs库的作用就是为了解决代码冲突,js模块的依赖关系等等问题
Seajs,一个Web模块加载框架,追求简单、自然的代码书写和组织方式,:Sea.js 遵循 CMD 规范,模块化JS代码。依赖的自动加载、配置的简洁清晰,可以让程序员更多地专注编码。
Seajs优缺点
优点:提高可维护性、模块化编程、动态加载,前端性能优化
SeaJs与JQuery的区别
什么是CMD 和AMD
js模块化规范—概念和模块化进化史以及模块化的问题的更多相关文章
- 一文彻底搞懂JS前端5大模块化规范及其区别
码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14577243.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...
- 模块化规范Common.js,AMD,CMD
随着网站规模的不断扩大,嵌入网页中的javascript代码越来越大,开发过程中存在大量问题,如:协同开发,代码复用,大量文件引入,命名冲突,文件依赖. 模块化编程称为迫切的需求. 所谓的模块,就是实 ...
- Node.js实战项目学习系列(3) CommonJS 模块化规范
前言 想开始编写Node.js代码,那么我们就必须先熟悉它的模块化规范CommonJS,本文将详细讲解CommonJS规范 本文代码 >>> github 地址 CommonJS N ...
- js的模块化规范
js的模块化规范常见的有:AMD,CMD,commonJS,UMD,es6 前期在没有模块化的时候,js文件十分庞大,于是就按功能抽离划分为多个js文件. 但是在html页面通过script的方式加载 ...
- JS模块化规范CMD之SeaJS
1. 在接触规范之前,我们用模块化来封装代码大多为如下: ;(function (形参模块名, 依赖项, 依赖项) { // 通过 形参模块名 修改模块 window.模块名 = 形参模块名 })(w ...
- JS 模块化 - 02 Common JS 模块化规范
1 Common JS 介绍 Common JS 是模块化规范之一.每个文件都是一个作用域,文件里面定义的变量/函数都是私有的,对其他模块不可见.Common JS 规范在 Node 端和浏览器端有不 ...
- 模拟实现AMD模块化规范
目录 引子 再谈什么是闭包(闭包的产生)? 词法作用域 回到闭包 利用闭包编写模块 实现AMD模块化规范 写在最后 引子 本文最后的目的是模拟实现AMD模块化规范,而写下本文的原因是今天阅读到了< ...
- Java模块化规范之争(转载)
经过近20年的发展,Java语言已成为今日世界上最成功.使用的开发者人数最多的语言之一,Java世界中无数商业的或开源的组织.技术和产品共同构成了一个无比庞大的生态系统. 与大多数开发人员的普遍认知不 ...
- Javascript模块化规范
Javascript模块化规范 一.前端js模块化由来与演变 CommonJS 原来叫 ServerJS,推出 Modules/1.0 规范后,在 Node.js 等环境下取得了很不错的实践.09年下 ...
随机推荐
- JavaScript事件(含Demo)
主要事件: onclick 鼠标单击事件 onmouseover 鼠标经过事件 onmouseout 鼠标移开事件 onchange 文本框内容改变事件 onselect 文本框内容被选中事件 onf ...
- 异常: Call From * 9000 failed on connection exception: java.net.ConnectException: Connection refused: no further information; For more details see: http://wiki.apache.org/hadoop/ConnectionRefused
场景: eclipse链接不上阿里云hadoop解决: 将hadoop的配置文件中的ip改为内网IP即可
- mapper代理开发步骤
1:先写Mapper接口,UserMapper.java 2:然后遵循4条开发规范,写映射文件,UserMapper.xml 3:将映射文件,UserMapper.xml加入到SqlMapConfig ...
- 4 ;XHTML表格
1.表格的基本格式 2.<table>标签下的常用属性 3.<table>标签下的边框设置 4.<tr><th><td>标签下的常用属性 5 ...
- VMWAR-workstatuon : 安装win10、server 2008 r2、server 2012 r2
最新版的VMWAR 不是很文档,建议大家还是下载稳定版,截止当前最新版的为15,用了,有点问题. 换成14~ 可以了.(15创建虚拟机安装vmware tools 怎么都安装不了). 关于创建虚拟机, ...
- 二进制安装 kubernetes 1.12(二) - 安装docker, 部署Flannel网络
在 node 节点上安装 docker 参考 https://www.cnblogs.com/klvchen/p/8468855.html Flannel 工作原理: 部署Flannel网络 在 ma ...
- CSS字体样式属性
font-size 字号大小 一般推荐使用相对长度(px ,em),不推荐使用绝对长度(in,cmm,mm,pt) font-family 字体 1.可以同时指定多个字体,中间用英文状态的逗号隔开,英 ...
- Filter防止用户访问一些未被授权的资源
package com.drp.util.filter; import java.io.IOException; import javax.servlet.Filter; import javax.s ...
- 基于Python实现的死链接自动化检测工具
基于Python实现的死链接自动化检测工具 by:授客 QQ:1033553122 测试环境: win7 python 3.3.2 chardet 2.3.0 脚本作用: 检测系统中访问异常(请求 ...
- C# 简单实现直线方程,抛物线方程
本例子是简单的在WinForm程序中实现在坐标系中绘制直线方程,抛物线方程,点.重新学习解析几何方面的知识.仅供学习分享使用,如有不足之处,还请指正. 涉及知识点: 直线方程的表达方式:一般表达式Ax ...