前端模块化是将一个复杂的系统分解出多个模块,每一个模块职责单1、相互独立、高度解耦并可替换。通常前端模块化指的是Javascript的模块。最多见的是Nodejs的NPM包。javascript
模块化开发的四点好处:html
模块化也是组件化的基石,是构成如今色彩斑斓的前端世界的前提条件。前端
Javascript在早期的设计中就没有模块、包、类的概念,开发者须要模拟出相似的功能,来隔离、组织复杂的Javascript代码,咱们称为模块化。有了模块化以后的代码,咱们考虑更多的代码使用和维护成本问题,而后就有不少模块化的规范。常见的模块化规范有CommonJs、AMD、CMD、ES6 Module等规范。java
CommonJs是服务端模块化规范,Nodejs采用了这个规范并把它发扬光大。git
//example.js var n = 1; function sayHello( name ){ var name = name || "Tom"; return "Hello~"+name } function addFn(val){ var val = val.x+val.y; return val } module.exports ={ n:n, sayHello:sayHello, addFn:addFn } //main.js var example = require('./example.js'); var addNum = { "x":10, "y":5 } console.log( example )//查看example输出的对外模块接口; console.log( example.n )//1; console.log( example.sayHello("Jack") )// "Hello~ Jack"; console.log( example.addFn(addNum) ) //15;
CommonJS 加载模块是同步的,因此只有加载完成才能执行后面的操做。像Nodejs主要用于服务器的编程,加载的模块文件通常都已经存在本地硬盘,因此加载起来比较快,不用考虑异步加载的方式,因此CommonJS规范比较适用。但若是是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。因此就有了 AMD CMD 解决方案。es6
AMD 是客户端模块管理工具库RequireJS提出而且完善的一套模块化规范,AMD 是基于异步加载模块的方式。
特色 :异步加载,不阻塞页面的加载,能并行加载多个模块,可是不能按需加载,必须提早加载所需依赖github
// 用define 定义模块 define({ method1: function() {}, method2: function() {}, }); // 定义模块时引用其余模块 define(['module1', 'module2'], function(m1, m2) { ... }); // require 调用模块 require(['foo', 'bar'], function ( foo, bar ) { foo.doSomething(); });
CMD 是国内大牛玉伯提出来的,实现的库是SeaJs.编程
// test1.js define(function(require,exports,module){ ... module.exports={ ... } }) // test2.js define(function(require,exports,module){ var cmd = require('./test1') // cmd.xxx 依赖就近书写 // 经过 exports 对外提供接口 exports.doSomething = ... // 或者经过 module.exports 提供整个接口 module.exports = ... })
CMD与AMD的区别:浏览器
define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此处略去 100 行 var b = require('./b') // 依赖能够就近书写 b.doSomething() // ... }) // AMD 默认推荐的是 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() // 此处略去 100 行 b.doSomething() ... })
在 ES6 以前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,并且实现得至关简单,彻底能够取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
ES6 的模块自动采用严格模式,无论你有没有在模块头部加上"use strict"
;并使用export、import 命令实现导出引用模块。服务器
// profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export { firstName, lastName, year }; // main.js import { firstName, lastName, year } from './profile.js'; function setName(element) { element.textContent = firstName + ' ' + lastName; } //export default 命令 // export-default.js export default function () { console.log('foo'); } // import-default.js import customName from './export-default'; customName(); // 'foo'
ES6 Module 与 CommonJS 的区别
前端模块侧重的功能的封装,主要是针对Javascript代码,隔离、组织复制的javascript代码,将它封装成一个个具备特定功能的的模块。
模块能够经过传递参数的不一样修改这个功能的的相关配置,每一个模块都是一个单独的做用域,根据须要调用。
一个模块的实现能够依赖其它模块。
前端组件更多关注的UI部分,页面的每一个部件,好比头部,底部、内容区,弹出框均可以成为一个组件,每一个组件有独立的HTML、CSS、JS代码。
能够根据须要把它放在页面的任意部位,也能够和其余组件一块儿造成新的组件。一个页面是各个组件的结合,能够根据须要进行组装。
扩展:站在业务的角度架构的视角模块组件又能够这么分。
模块和组件都是系统的组成部分。
从逻辑角度拆分系统后,获得的单元就是“模块”。
从物理角度来拆分系统后,获得的单元就是“组件”。
划分模块的主要目的是职责分离,划分组件的主要目的是单元复用。
假设咱们要作一个学生管理系统,这个系统从逻辑的角度拆分,能够分为“登陆注册模块”“我的成绩模块”;从物理的角度来拆分,能够拆分为Nginx、Web服务器、MySql。
参考:
浅谈前端模块化
前端模块与组件的区别
30分钟学会前端模块化开发
前端模块化、组件化的理解
知乎玉伯回复CMD和AMD的区别[阮一峰ES6 Module 语法]()[ES6 Module与CommonJs的差别化]()从零开始学架构(李运华)