详解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')

猜你喜欢

转载自blog.csdn.net/qq_43692768/article/details/110500837