详解js模块化------CommonJS / AMD / CMD / ES6

一、什么是模块 / 模块化

  在学习js模块化之前,我们要知道什么是模块 / 模块化。

  模块/模块化:将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起。块的内部数据(实现)是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信。

二、为什么要使用模块化

  网站正在变成网络应用程序,代码复杂度随着网站的扩大而增加, 开发者需要高度解耦的JS文件/模块管理网页的业务逻辑,在部署时也需要优化代码,所以Javascript模块化编程,已经成为一个迫切的需求。

三、模块化的好处

  • 避免命名冲突(减少命名空间污染);
  • 更好的分离, 按需加载;
  • 更高复用性;
  • 高可维护性。

四、模块化规范—CommonJS

1、说明

  • 每个文件都可当作一个模块;
  • 在服务器端: 模块的加载是运行时同步加载的;
  • 在浏览器端: 模块需要提前编译打包处理。

2、基本语法

a. 暴露模块

方法一:module.exports = value

方法二:exports.xxx = value

b. 引入模块

require(xxx)
第三方模块:xxx为模块名
自定义模块: xxx为模块文件路径

3、实现

a. 服务器端实现(Node.js)
(1)、创建项目结构

目录

(2)、定义模块代码

  module1.js

//暴露一个对象 module.exports=value
module.exports={
  msg:"module1",
  foo(){
    console.log("foo()",this.msg);
  }
};

  module2.js

//暴露一个函数 module.exports=function(){}
module.exports=function () {
  console.log("modile2");
};

  module3.js

//exports.xxx=value;
exports.bar=function () {
  console.log("bar", "module3");
};

  app.js

let module1=require("./modules/module1");
let module2=require("./modules/module2");
let module3=require("./modules/module3");

module1.foo();
module2();
module3.bar();
(3)、安装node.js,并通过node运行app.js

命令: node app.js
工具: 右键–>运行

  运行结果
运行结果

b. 浏览器端实现(Browserify)
(1)、基于以上,下载browserify

全局: npm install browserify -g
局部: npm install browserify --save-dev

(2)、打包处理js

browserify js/src/app.js -o js/dist/bundle.js

(3)、创建index.html,在页面中引入bundle.js

<script type="text/javascript" src="js/dist/bundle.js"></script>

五、模块化规范—AMD

1、说明

  • 专门用于浏览器端
  • 模块的加载是异步的

2、基本语法

a. 暴露模块
(1)、定义没有依赖的模块
define(function(){
  return 模块
})
(2)、定义有依赖的模块
define(['module1', 'module2'], function(m1, m2){
	return 模块
})
b. 引入模块
require(['module1', 'module2'], function(m1, m2){
	使用m1/m2
})

3、实现(浏览器端)

a. 不使用AMD规范
(1)、创建项目结构

noAMD目录

(2)、定义模块代码

  module1.js

(function (window) {
  let msg="module1";
  function showMsg(){
    console.log(msg);
  }
  window.showMsg=showMsg;
})(window);

  module2.js

(function (window,showMsg) {
  data="module2";
  function getData() {
    console.log(data);
    showMsg();
  }

  window.getData=getData;
})(window,showMsg);

  app.js

(function (getData) {
  getData();
})(getData);

  index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>01_NoAMD</title>
</head>
<body>

<script src="js/module1.js"></script>
<script src="js/module2.js"></script>
<script src="js/app.js"></script>
</body>
</html>
(3)、引起的问题

  页面中加入了多个js,加载页面时,请求过多;module2.js依赖module1.js,所以module1.js必须放在module2.js的前面,但在实际开发中,这种依赖关系模糊,难以维护。

b. AMD规范(Require.js)
(1)、创建项目结构

目录

(2)、定义require.js的模块代码

  module1.js

define(function () {
  let msg="require_module1";
  function showMsg(){
    console.log(msg);
  }
  return {showMsg};
});

  module2.js

define(function () {
  let msg="require_module1";
  function showMsg(){
    console.log(msg);
  }
  return {showMsg};
});

  app.js

(function () {
  requirejs.config({
    baseURL:"js/",
    paths:{
      module1:"./module/module1",
      module2:"./module/module2",
      jquery:"./lib/jquery-1.10.1"
    }
  });
  requirejs(['module2','jquery'],function (module2,$) {
    $("body").css("background","deeppink");
    module2.getData();
  });

  // requirejs(['module2'],function (module2,) {
  //   module2.getData();
  // });
})();
(3)、创建index.html,下载require.js, 并在.html文件中引入
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script data-main="js/app.js" src="js/lib/require.js"></script>
</body>
</html>

六、模块化规范—CMD

1、说明

  • 专门用于浏览器端, 模块的加载是异步的
  • 模块使用时才会加载执行

2、基本语法

a. 暴露模块
(1)、定义没有依赖的模块
define(function(require, exports, module){
	exports.xxx = value
	module.exports = value
})
(2)、定义有依赖的模块
define(function(require, exports, module){
	//引入依赖模块(同步)
	var module2 = require('./module2')
	//引入依赖模块(异步)
  	require.async('./module3', function (m3) {
    	
  	})
	//暴露模块
	exports.xxx = value
})
b. 引入模块
define(function (require) {
	var m1 = require('./module1')
	var m4 = require('./module4')
	m1.show()
	m4.show()
})

3、实现(浏览器端)

(1)、创建项目结构

目录

(2)、定义模块代码

  module1.js

define(function (require,exports,modules) {
  let msg="module1";
  function foo() {
    console.log(msg);
  }
  modules.exports={foo};
});

  module2.js

define(function (require,exports,module) {
  let data="module2";
  function bar() {
    console.log(data);
  }
  exports.bar=bar;
});

  module3.js

define(function (require,exports,module) {
  let data="module3";
  function fun() {
    console.log(data);
  }
  module.exports={fun}
});

  module4.js

define(function (require,exports,module) {
  let msg="module4";

  let module2=require("./module2");
  module2.bar();

  require.async("./module3",function (module3) {
    module3.fun();
});

  function showMsg() {
    console.log(msg);
  }
  exports.showMsg=showMsg;
  
});

  app.js

define(function (require) {
  let m1=require("./modules/module1");
  let m4=require("./modules/module4");

  m1.foo();
  m4.showMsg();
});
(3)、创建index.html,下载sea.js, 并在.html文件中引入
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>05_CMD_SeaJS</title>
</head>
<body>

<script src="js/libs/sea.js"></script>
<script>
  seajs.use("./js/app.js");
</script>
</body>
</html>

七、模块化规范—ES6

1、说明

  • 依赖模块需要编译打包处理

2、基本语法

a. 暴露模块

暴露模块: export

b. 引入模块

引入模块: import

3、实现(浏览器端)

(1)、创建项目结构

在这里插入图片描述

(2)、定义package.json文件

{
“name” : “es6-babel-browserify”,
“version” : “1.0.0”
}

(3)、安装babel-cli, babel-preset-es2015和browserify

npm install babel-cli browserify -g
npm install babel-preset-es2015 --save-dev

  说明:cli:command line interface 命令行接口;
     preset 预设(将es6转换成es5的所有插件打包)。

(4)、定义 .babelrc 文件

{
“presets”: [“es2015”]
}

(5)、定义模块代码

  module1.js

export function fun(){
  console.log("fun() module1");
}

export function fun2() {
  console.log("fun2() module2");
}

  module2.js

function foo() {
  console.log("foo() module2");
}

function bar() {
  console.log("bar() module2");
}

export {
  foo,
  bar
}

  module3.js

export default function () {
  console.log("默认暴露");
}

  app.js

// import $ from "jquery";
import {fun,fun2} from "./module1";
import {foo,bar} from "./module2";
import module3 from "./module3";

// $("body").css("background","green");
fun();
fun2();
foo();
bar();
module3();
(5)、编译

使用Babel将ES6编译为ES5代码(但包含CommonJS语法) :
babel js/src -d js/lib
使用Browserify编译js :
browserify js/lib/app.js -o js/lib/bundle.js

(6)、创建index.html, 在.html文件中引入编译后的bundle.js
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>06_ES6_   Babel   _    Browderify   </title>
</head>
<body>
<script src="js/dist/bundel.js"></script>
</body>
</html>
(7)、引入第三方模块(jQuery)

下载jQuery模块:
npm install jquery@1 --save

在app.js中引入并使用
import $ from 'jquery'
$('body').css('background', 'red')

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CommonJSAMD/CMD是两种不同的模块化规范,而ES6则是JavaScript的新标准,也包含了模块化的支持。 CommonJS主要用于服务器端的模块化,其特点是同步加载模块,模块输出的是一个对象,可以通过require()方法加载模块。 AMD/CMD则主要用于浏览器端的模块化,其特点是异步加载模块,模块输出的是一个函数,可以通过define()方法定义模块。 ES6模块化则是JavaScript的新标准,其特点是静态加载模块,模块输出的是一个变量,可以通过import和export语句加载和定义模块。 总的来说,CommonJSAMD/CMD是旧的模块化规范,而ES6则是新的标准,具有更好的性能和可读性。 ### 回答2: CommonJS是一个模块规范,旨在使JavaScript在服务器端上运行。它在Node.js上得到广泛应用,主要是用于模块管理和代码复用。它定义了模块如何定义以及如何导出和导入模块。 AMDCMD是两个常用的模块规范,旨在更好地管理浏览器端的模块。AMDCMD规范都优化了服务器端的加载速度,提高了代码复用性。 ES6是一个新版的JavaScript规范,它增加了许多新的语言特性和语法糖,使得JavaScript更具有可读性和可维护性。ES6规范中引入了模块的概念,通过import和export可以轻松管理模块,并且JS引擎会进行编译优化以提高性能。 CommonJSAMD/CMD的主要区别在于模块的加载方式。CommonJS采用同步加载方式,即导入模块时会等待所有依赖模块都加载完毕后再执行导入操作。这会造成一定的阻塞,但是可以保证依赖关系正确。而AMD/CMD采用异步加载方式,即采用回调函数的方式导入模块,不会造成阻塞,但是需要手动管理依赖关系。 ES6模块的最大优点在于静态编译。在使用ES6模块时,浏览器可以在代码加载时对模块进行静态分析,从而明确哪些模块需要导入和导出,它们的依赖关系以及导入的值。这是在CommonJSAMD/CMD等模块规范中无法做到的。ES6模块的缺点是目前还不是所有的浏览器都支持。 ### 回答3: CommonJSAMDCMDES6JavaScript使用的模块系统。它们都试图将代码组织为可重用的模块,但它们在一些方面不同。 CommonJS是一个使用Node.js的模块系统,它允许在服务器端和客户端共享模块。CommonJS模块是同步加载的,这意味着当模块被请求时,它会立即加载模块,并立即执行模块的代码。 AMD(异步模块定义)是在浏览器环境中使用的模块系统,它允许异步加载模块。当一个模块被请求时,AMD并不会像CommonJS那样立即加载它,而是等待其他模块完成加载。然后,当模块被加载和运行时,AMD会运行任何模块和依赖项的回调函数。 CMD(通用模块定义)是一个应用于浏览器和服务器端的模块系统,它的特点是就近依赖,在需要时才进行依赖的加载。CMD模块是通过define函数来定义的。在调用define时,会传递一个回调函数,该回调函数可以使用require来访问其他模块。 ES6模块是JavaScript的原生模块系统,它允许在JavaScript中定义模块。ES6模块是静态的,这意味着每个模块都是在编译时确定的。ES6模块支持默认导出和命名导出。 在总体上,CommonJS适合于服务器端,AMDCMD适合于浏览器端,而ES6则是一个全面的模块系统,适用于任何环境。不同的模块系统在实现上有所不同,选择哪种类型的模块系统需要根据具体情况进行判断。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值