一、前端模块化规范
二、CommonJS
1、CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}
1.1、require():用来引入外部模块;
1.2、exports:对象用于导出当前模块的方法或变量,唯一的导出口;
1.3、module:对象就代表模块本身。
2、NodeJS中使用CommonJS模块管理
2.1、模块定义:根据commonJS规范,一个单独的文件是一个模块,每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非为global对象的属性。
2.1.1、说明:模块只有一个出口,module.exports对象,我们需要把模块希望输出的内容放入该对象。
2.1.2、common.js模块定义
let message="Hello CommonJS!"; module.exports.message=message; module.exports.add=(m,n)=>console.log(m+n);
2.2、模块依赖
2.2.1、说明:加载模块用require方法,该方法读取一个文件并且执行,返回文件内部的module.exports对象。
2.2.2、app.js 模块依赖
var common=require("./common"); //读取common.js文件
console.log(common.message); //调用
common.add(100,200);
2.3、测试运行
安装好node.JS
打开控制台,可以使用cmd命令
3、在浏览器中使用CommonJS 模块管理
3.1、由于浏览器不支持 CommonJS 格式。要想让浏览器用上这些模块,必须转换格式。
例:创建index.html直接引用app.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="js/app.js"></script> </body> </html>
报错,提示require没有被定义
3.2、方法:使用browserify,可以把nodejs的模块编译成浏览器可用的模块,解决上面提到的问题。本文将详细介绍Browserify实现Browserify是目前最常用的CommonJS格式转换的工具
3.2.1、安装browserify
使用下列命令安装browserify
npm install -g browserify
3.2.2、转换
使用下面的命令,就能将app.js转为浏览器可用的格式apps.js
browserify app.js > apps.js
生成apps.js文件
apps.js文件内容:
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ var common=require("./common"); console.log(common.message); common.add(100,200); },{"./common":2}],2:[function(require,module,exports){ let message="Hello CommonJS!"; module.exports.message=message; module.exports.add=(m,n)=>console.log(m+n); },{}]},{},[1]);
index.html引用apps.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="js/apps.js"></script> </body> </html>
运行结果:
三、AMD(Asynchromous Module Definition) 异步模块定义
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出
AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。
适用AMD规范适用define方法定义模块。
1、定义模块:define(id,dependencies,factory)
——id 可选参数,用来定义模块的标识,如果没有提供该参数,脚本文件名(去掉拓展名)
——dependencies 是一个当前模块用来的模块名称数组
——factory 工厂方法,模块初始化要执行的函数或对象,如果为函数,它应该只被执行一次,如果是对象,此对象应该为模块的输出值。
2、加载模块:require([dependencies], function(){});
require()函数接受两个参数:
——第一个参数是一个数组,表示所依赖的模块;
——第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块
3、简单示例
模块定义:amd.js
//定义模块 define(function(){ return{ message:"Hello AMD!", add:function(n1,n2){ return n1+n2; } } })
模块依赖:app.js
require(['amd'],function(amd){ console.log(amd.message); console.log(amd.add(100,200)) })
下载:require.js
官网:http://www.requirejs.cn
浏览器调用:index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="AMD/require.js" data-main="AMD/app.js"></script>
</body>
</html>
结果:
4、依赖第三方的库(AMD依赖jQuery)
导入jQuery
app.js代码
require(['amd','jquery'],function(amd){
console.log(amd.message);
console.log(amd.add(100,200));
$("body").text("引用了第三方插件")
})
结果:
三、CMD(Common Module Definition)通用模块定义
实例:
导入Seajs库
去官网下载最新的seajs文件,http://seajs.org/docs/#downloads
目录结构:
定义模块:
cmd.js
define(function(require,exports,module){ var obj={ msg:"Hello SeaJS!", show:()=>console.log(obj.msg) } exports.cmd=obj; })
导入模块:
app.js
seajs.config({ //Sea.js 的基础路径(修改这个就不是路径就不是相对于seajs文件了) base: './js/', //别名配置(用变量表示文件,解决路径层级过深和实现路径映射) alias: { 'jquery': 'CMD/jquery' }, //路径配置(用变量表示路径,解决路径层级过深的问题) paths: { 'm': 'CMD/' } }) seajs.use(["m/cmd.js",'jquery'],function(cmd,$){ cmd.cmd.show(); $("body").text("Hello CMD!"); })
浏览器调用:
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="js/sea.js"></script> <script src="js/CMD/app.js"></script> </body> </html>
结果:
四、原生模块化(ECMAScript模块化)
实例:
目录结构:
定义模块:
es6.js
//定义模块 export let msg="Hello Es6(原生模块)"; export function add(n,m){ return n+m; }
导入模块:
es6.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script type="module"> //导入 import {msg,add} from './es6/es6.js'; console.log(add(100,200)); console.log(msg); </script> </body> </html>
结果:
五、UMD(通用的模块定义)
UMD(Universal Module Definition)通用的模块定义、UMD等于CommonJS加上AMD。UMD的工作其实就是做了一个判断:
- - 先判断当前环境对NodeJs支持的模块是否存在,存在就用Node.js模块模式(exports)。
- - 如果不支持,就判断是否支持AMD(define),存在就使用AMD方式加载。
CommonJs和AMD风格一样流行,似乎缺少一个统一的规范。所以人们产生了这样的需求,希望有支持两种风格的“通用”模式,于是通用模块规范(UMD)诞生了。
UMD示例
1、定义模块Utils.js
(function (global, factory) { if (typeof define === 'function' && (define.amd || define.cmd)) { // AMD规范. 注册一个匿名模块,兼容AMD与CMD define([], factory); } else if (typeof module === 'object' && module.exports) { //CommonJS规范,NodeJS运行环境 module.exports = factory(); } else { //浏览器全局对象注册 global.UMD = factory(); } }(this, function () { var msg = "UMD!"; //返回要导出的对象 return { show: function () { console.log("Hello " + msg); } }; }));
2、在CommonJS规范下运行
useUtils.js
var utils=require('./Utils.js'); utils.show();
运行结果:
在AMD规范下运行
app.js
require(['amd','jquery','../Utils.js'],function(amd,$,u){ console.log(amd.message); console.log(amd.add(100,200)); $("body").text("引用了第三方插件"); u.show(); })
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="require.js" data-main="app.js"></script> </body> </html>
运行结果:
3、在CMD规范下运行
app.js
seajs.use(["cmd.js",'jquery','../Utils.js'],function(cmd,$,u){ cmd.cmd.show(); $("body").text("Hello CMD!"); u.show(); })
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="sea.js"></script> <script src="app.js"></script> </body> </html>
运行结果:
4、原生浏览器环境运行
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="../Utils.js"></script> <script> UMD.show(); </script> </body> </html>
运行结果: