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

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. glPixelStorei 详解 包括像素传输

    3.glPixelStore 像glPixelStorei(GL_PACK_ALIGNMENT, 1)这样的调用,通常会用于像素传输(PACK/UNPACK)的场合.尤其是导入纹理(glTexImag ...

  2. AtCoder Beginner Contest 133 F Colorful Tree

    Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...

  3. Oracle查看数据占用的空间和数据文件实际空间的信息

    可以使用如下sql: select 'bgdrac' database,t11.username,t11.default_tablespace tablespace_name,segment_size ...

  4. mysql打开报错2013解决办法

    修改mysql配置文件 在[mysqld]下面设置skip-name-resolve 重启mysql from :https://www.jb51.net/article/52637.htm

  5. PHP返回JSON数据及中文编码问题的解决方案

    在处理app接口的时候 ,中文在经过json_encode之后 变成\ \格式 想在返回接口的时候  中文不被转换 解决办法 第一种解决办法 exit(json_encode($result,JSON ...

  6. TCP/UDP Socket调试工具提供了TCP Server,TCP Client,UDP Server,UDP Client,UDP Group 五种Socket调试方案。

    一.TCP通信测试: 1)   创建TCP Server: 选中左方的TCP Server, 然后点击”创建”按钮,软件弹出监听端口输入框 输入监听端口后,即创建了一个在指定端口上进行监听的TCP S ...

  7. [2019年湘潭大学程序设计竞赛(重现赛)H chat][背包dp]

    链接:https://ac.nowcoder.com/acm/contest/893/H来源:牛客网 题目描述 在Casya生活的世界里,一天由m个小时组成. 最近Casya的女神终于答应在接下来的n ...

  8. mapbox-gl空间分析插件turf.js使用介绍

    mapbox-gl能够方便地显示地图,做一些交互,但是缺少空间分析功能,比如绘制缓冲区.判断点和面相交等等. turf.js是一个丰富的用于浏览器和node.js空间分析库,官网 http://tur ...

  9. mysql 解决忘记密码 mysql5.7 远程登录不上MySQL(解决腾讯服务器初始mysql密码问题)

    一.修改MySQL启动配置文件 #如果不知道配置文件,先查找find / -name my.cnf#编辑配置文件 vim /etc/my.cnf 在[mysql]  下面第一行加入 skip-gran ...

  10. 010_STM32程序移植之_lib库建立

    STM32之lib库建立 1. 测试环境:STM32C8T6 2. 测试接口: 3.串口使用串口一,波特率9600 单片机引脚------------CH340引脚 VCC-------------- ...