当项目越来越大时,会遇到一些问题:

1.命名冲突

2.文件依赖

所有就有了javascript模块化开发概念。

模块化开发的演变:

1.函数块:最开始用全局函数将代码块包括在函数体内,然后把很多函数写在一个js文件,然后引入js文件,这种方式会导致:全局变量污染和命令冲突,模块之间的关系也不明确。

2.命名空间:把函数和变量封装在对象里,可以较好的避免命名冲突问题。但是这方式会导致:多层级嵌套(命名空间越来越长),暴露了所有的模块成员,内部状态可以被外部改写,不安全。

3.私有共有成员分离:将函数包裹在立即执行函数(达到函数外部无法访问内部变量的效果)里,以返回的方式选择性对外暴露内部成员。在立即执行函数里形成了一个私有作用域,私有空间的变量和函数不会影响到全局作用域。从某种意义上来说,解决了变量命名冲突的问题。

var calculator = (function () {
// 这里形成一个单独的私有的空间
// 私有成员的作用:
// 1、将一个成员私有化
// 2、抽象公共方法(其他成员中会用到的) // 私有的转换逻辑
function convert(input){
return parseInt(input);
} function add(a, b) {
return convert(a) + convert(b);
}
function subtract(a, b) {}
function multiply(a, b) {}
function divide(a, b) {}
return {
add : add,
subtract : subtract,
multiply : multiply,
divide : divide
}
})();

  

4.模块的拓展与维护

// 计算模块
(function (calculator) {
function convert(input) {
return parseInt(input);
}
calculator.add = function(a, b) {
return convert(a) + convert(b);
}
window.calculator = calculator;
})(window.calculator || {}); // 新增需求
(function (calculator) {
calculator.remain = function (a , b) {
return a % b;
}
window.calculator = calculator;
})(window.calculator || {}); alert(calculator.remain(4,3));

  

这种方式有利于对庞大的模块的子模块划分。

5.第三方依赖的管理

(function (calculator , $) {
// 依赖函数的参数,是属于模块内部
// console.log($);
calculator.remain = function (a , b) {
return a % b;
}
window.calculator = calculator;
})(window.calculator || {} , jQuery);

  

传入依赖模块jQuery, 立即执行函数空间里就可以使用第三方依赖了。

创建模块的原则:高内聚低耦合,模块内相关性高,模块间关联低。单一职责

模块使用场景:

1.业务复杂

2.重复逻辑多

3.可拓展性要求高

最后演变到模块化规范:

服务端主要有CommonJS(Node.js 就是基于CommonJS规范实现的模块化 ,webpack也实现了对CommonJS原生支持)

CommonJS的核心思想就是通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或者 module.exports 来导出需要暴露的接口,这个规范里,每个文件就是一个模块
其内部定义的变量是属于这个模块的,不会对外暴露,也就是说不会污染全局变量。例如
// a.js
var x = 5;
var addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX; 这里的module代表了这个模块,module的exports属性就是对外暴露提供的接口,可以对外导出外部可以访问的变量,如x, addX  
这样就可以在其他模块中引入这个模块了
var example = require('./a.js');
console.log(example.x); // 5
CommonJS规范是同步加载模块的,在服务器端,文件都是保存在硬盘上,所以同步加载没有问题,但是对于浏览器端,需要将文件从服务器端请求过来,那么同步加载就不适用了,所以,CommonJS是不适用于浏览器端的。

客户端主要有:AMD( 实现有RequireJS ) / CMD(实现有SeaJS),随着ES6模块化规范的实现和普及,第三方的模块化实现将会慢慢的淘汰。

  AMD是非同步加载模块,允许函数回调,如Require.js,需提前加载所有模块。

  CMD是按需加载模块的(可以依赖就近),不需要在模块开始就加载所有依赖。

AMD和CMD 规范 模块加载区别:前者是对于依赖的模块提前执行,后者是延迟执行。前者提倡依赖前置,后者提倡依赖就近,只需要在用到某个模块时再require.

// AMD
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 注意标红的,通过函数回调的方式将引入的依赖赋值给标红的变量,然后整个块就可以利用这个引入的依赖了
a.doSomething()
// 此处略去 100 行
b.doSomething()
...
});
// CMD
define(function(require, exports, module) {
var a = require('./a')
a.doSomething()
// 此处略去 100 行
var b = require('./b')
// 依赖可以就近书写
b.doSomething()
// ...
});

 

JavaScript 模块化主要有三种方案:

1.CommonJS

// module math.js
module.exports = function add (a, b) { return a + b; } // main.js
var {add} = require('./math'); console.log('1 + 2 = ' + add(1,2);

  

2.AMD / CMD

// module add.js
define(function () {
return {
add: function (a, b) add { return a + b; }
};
}); // main.js
require(['add'], function (add) { console.log('1 + 2 = ' + add(1,2);
});

  

3.ES6

// module add.js
export function add (a, b) { return a + b; } // main.js
import {add} from 'add.js';

  

之前的几种模块化方案都是前端社区自己实现的,只是得到了大家的认可和广泛使用,而ES6的模块化方案是真正的规范。 在ES6中,我们可以使用 import 关键字引入模块,通过 export 关键字导出模块,功能较之于前几个方案更为强大,也是我们所推崇的,但是由于ES6目前无法在浏览器中执行,所以,我们只能通过babel将不被支持的import编译为当前受到广泛支持的 require。

之前在想这个问题之前,一直有个疑问,浏览器怎么支持的require,exports, module, define 这些字段的? 。。。

很二逼的疑问,因为 require.js  sea.js 就是用来支持浏览器提供这些字段的,也就是说在我们自己编写的模块之前需要先引入这些规范实现的库文件

<script src="./require.js"></script>

<script src="./otherModule.js"></script>

参考链接:https://www.jianshu.com/p/3832c00a44a7

http://www.ruanyifeng.com/blog/2015/05/commonjs-in-browser.html

JavaScript 模块化的更多相关文章

  1. Javascript模块化编程(三):require.js的用法

    Javascript模块化编程(三):require.js的用法 原文地址:http://www.ruanyifeng.com/blog/2012/11/require_js.html 作者: 阮一峰 ...

  2. Javascript模块化编程(二):AMD规范

    Javascript模块化编程(二):AMD规范   作者: 阮一峰 原文地址:http://www.ruanyifeng.com/blog/2012/10/asynchronous_module_d ...

  3. Javascript模块化编程(一):模块的写法

    Javascript模块化编程(一):模块的写法 作者: 阮一峰 原文链接:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html ...

  4. Javascript模块化编程(二):AMD规范(转)

    这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要 ...

  5. Javascript模块化编程(一):模块的写法(转)

    随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂. 网页越来越像桌面程序,需要一个团队分工协作.进度管理.单元测试等等......开发者 ...

  6. Javascript模块化规范

    Javascript模块化规范 一.前端js模块化由来与演变 CommonJS 原来叫 ServerJS,推出 Modules/1.0 规范后,在 Node.js 等环境下取得了很不错的实践.09年下 ...

  7. Javascript模块化开发,使用模块化脚本加载工具RequireJS,提高你代码的速度和质量。

    随着前端JavaScript代码越来越重,如何组织JavaScript代码变得非常重要,好的组织方式,可以让别人和自己很好的理解代码,也便于维护和测试.模块化是一种非常好的代码组织方式,本文试着对Ja ...

  8. Javascript 模块化开发上线解决方案

    最近又换部门了,好频繁地说...于是把这段时间搞的小工具们简单整理了一下,作了一个小的总结.这次用一个简单业务demo来向大家介绍一下Javascript模块化开发的方式和自动化合并压缩的一些自己的处 ...

  9. Javascript模块化编程(二):AMD规范 作者: 阮一峰

    声明:转载自阮一峰的网络日志 这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可 ...

  10. Javascript模块化编程(一):模块的写法 作者: 阮一峰

    声明:转载自阮一峰的网络日志 随着网站逐渐变成"互联网应用程序",嵌入网页的Javascript代码越来越庞大,越来越复杂. 网页越来越像桌面程序,需要一个团队分工协作.进度管理. ...

随机推荐

  1. We're sorry but mobile doesn't work properly without JavaScript enabled. Please enable it to continue.

    vue过程中遇见这个问题:We're sorry but mobile doesn't work properly without JavaScript enabled. Please enable ...

  2. 巧用linux云服务器下的的/dev/shm/,避开磁盘IO不给力!

    巧用linux云服务器下的的/dev/shm/,避开磁盘IO不给力! 一.什么是tmpfs和/dev/shm/? tmpfs是Linux/Unix系统上的一种基于内存的文件系统.tmpfs可以使用您的 ...

  3. Http协议与TCP协议

    背景 在日常工作中,经常会遇到某某框架是基于Http协议或者TCP协议,今天,就针对于该协议,整理下 从本质上来说,Http协议与TCP协议是应用在不同网络层,Http协议处于应用层,TCP处于传输层 ...

  4. Nginx入门(一)——安装和配置

    1.下载地址 http://nginx.org/en/download.html 2.启动Nginx 进入window的cmd窗口,输入如下图所示的命令,进入到nginx目录(F:/nginx-1.8 ...

  5. 27、AOP-AOP功能测试

    27.AOP-AOP功能测试 AOP : [动态代理]指程序运行期间动态的将某段代码切入到制定方法位置进行运行的编程方式. 导入AOP模块:Spring AOP(spring-aspects) 定义一 ...

  6. .Net Core: 跨域Cros概要

    读取配置 public class AppConfig { public static IConfigurationRoot Configuration { get; set; } public st ...

  7. windows版idea 2018.3.5版 永久激活教程

    1.下载idea并安装:https://download.jetbrains.com/idea/ideaIU-2018.3.5.exe?_ga=2.179947812.1869744014.15658 ...

  8. 顺序表Vector

    程序中会使用数据结构:例如:顺序表.链表.二叉树: 数据结构在底层中本质上只有两种:数据之间挨着和不挨着:   1.关于Vector

  9. csv和xlsx区别

    CSV是文本文件,用记事本就能打开.XLS 是二进制的文件只有用 EXCEL 才能打开: CSV 文件格式只能保存活动工作表中的单元格所显示的文本和数值.数据列以逗号分隔,每一行数据都以回车符结束.如 ...

  10. 解决GitHub下载速度太慢的问题

    更改hosts文件: Windows 更改C:\Windows\System32\drivers\etc\hosts文件,在文件中追加219.76.4.4 github-cloud.s3.amazon ...