zoukankan      html  css  js  c++  java
  • 模块化编程(2)

    模块存在的价值是为了能够更方便地复用代码 , 更加有利于功能的封装
    但是如果要实现的话 , 就必须要求每个人都按照同样的方式去编写模块
    目前通行的JavaScript模块规范有两种 , 分别是CommonJSAMD

    CommonJS

    从node.js出现之后 , 将JavaScript用于服务器编程
    同时也标志着JS的模块化编程正式诞生
    在网页环境下 , 没有模块也不是特别大的问题 , 因为网页程序的复杂性和规模都相对有限 , 但是在服务器端就必须要有模块 , 否则服务器端程序就会难以扩展和维护

    nodejs的模块系统 , 就是按照CommonJS规范实现的
    这个规范当中 , 有一个全局方法 require , 用于加载模块

    var mod1 = require("module1");
    mod1.biz();
    

    AMD

    有了在服务端可用的模块化编程方式 , 大家很自然就想要在客户端也能实现的方式 , 并且最好能够兼容
    这样同样的一个模块的代码 , 不用修改任何内容就可以同时应用于服务端和客户端

    但是如果直接套用在nodejs当中的实现方式 , 就会存在线程阻塞的问题
    也就是必须要等require方法执行完毕 , 加载运行这个模块的代码之后 , 后面的代码才会被执行
    对于服务端来说 , 这并不是什么问题 , 因为代码都在本地 , 不可能出现长期阻塞的问题
    但是对于客户端来说 , js文件需要发送http请求去获取 , 所以同步加载的方式就十分影响性能了

    AMD ( Asynchronous Module Definition 异步模块定义 ) , 这种规范的要求是采用异步方式加载模块
    形式如下 :

    require(["module1"], function(mod) {
    	mod.biz();
    });
    

    规范只是约定一种形式 , 具体要应用的话需要有对应的库来实现
    这里通过require.js来介绍

    require.js

    http://www.requirejs.cn/

    require.js主要解决两个问题

    1. 实现js文件的异步加载 , 避免网页失去响应
    2. 管理模块之间的依赖性 , 便于代码的编写和维护

    使用require.js需要指定一个主模块 , 以及在主模块中可以去引入若干个子模块 , 主模块相当于是程序执行的入口
    ( 如果没有子模块的话就不需要require.js了 )

    目录结构

    data-main入口点

    <script src="js/require.js" data-main="js/main"></script>
    

    js目录下的main.js就是作为主模块 , 后面的.js可以省略

    子模块的编写方式

    require.js加载的模块 , 采用AMD规范 , 也就是说模块必须按照AMD的规范来写
    模块必须采用特定的define函数来定义

    //module1.js
    define(function(){
    	return {
    		biz : function(){
    			console.log("子模块的方法");
    		}
    	}
    })
    

    这个函数返回的对象就是这个模块需要暴露出的对象

    如果该模块需要依赖其他模块

    //module2.js
    define(["module1"],function(mod1){
    	function biz2() {
    		return mod1.biz() + "ok";
    	}
    	return {
    		biz : biz2
    	}
    });
    

    主模块的编写方式

    //main.js
    require(["modules/module1","modules/module2"], 
    function(mod1,mod2){
    	//mod1和mod2分别是在子模块中暴露出的对象
    });
    

    require函数接受两个参数 , 第一个参数是子模块的相对路径和名称 ( 如果在同一个路径下可以不加路径 ) , 必须是一个数组
    第二个参数是子模块加载完成之后执行的回调函数

    更加灵活的自定义加载

    模块的引入采用的是子模块的js文件与主模块文件的相对位置
    如果要加在的子模块较多 , 这么相对路径就需要加在每个子模块的前面
    为了更清晰一些 , 我们可以采用下面的方式

    require.config({
    //注意这里的baseUrl是相对于引入主模块的页面的路径
    //页面是 /require_demo/test.html
    //子模块位于 /require_demo/other/module3.js
    	baseUrl : "./other/",
    	paths : {
    		mod3 : "module3",
    		mod4 : "module4"
    	}
    });
    //上面的代码相当于对子模块的路径创建了映射
    //下面才是真正引入模块
    require(["mod3","mod4"], function(mod3, mod4){
    	mod3.biz3();
    	mod4.biz4();
    });
    

    上面的写法其实就等价于

    require(["../other/module3","../other/module4"],
    function(mod3, mod4){
    	mod3.biz3();
    	mod4.biz4();
    });
    

    paths里面也可以直接使用完整的网络URL地址

    加载非规范的模块

    采用上面的方式去加载的子模块 , 模块当中必须按照AMD的规范去写
    如果子模块本身并不符合这个要求
    在不方便修改子模块的情况下 , 我们可以采用如下的方式去加载

    require.config({
    	shim : {
    		underscore : {
    			exports : "_"
    		}
    	},
    	paths : { //这部分并没有什么差别
    		underscore : "./plugins/underscore"
    	}
    });
    
    require(["underscore"], function(_) {
    	//测试代码
    	_.each([1,10,20],console.log);
    });
    

    未按照AMD规范编写的模块 , 通常采用的是暴露出一个变量放入到window当中作为全局变量 , 比如underscore这个库 , 暴露出的就是_

    模块依赖性声明
    
    shim : {
    	"jquery.scroll" : {
    		deps : ["jquery"],
    		exports : "jQuery.fn.scroll"
    	}
    }
    
  • 相关阅读:
    业余草双因素认证(2FA)教程
    业余草网站热门关键字
    微博爬虫“免登录”技巧详解及 Java 实现(业余草的博客)
    业余草通告CSDN博客用户zhang__ao非法转载文章的公告
    CODE大全给你推荐几个免费的leapftp 注册码
    业余草最新热门博客推荐
    莫比乌斯反演
    P5091 【模板】欧拉定理
    LaTeX Test
    P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
  • 原文地址:https://www.cnblogs.com/programInit/p/6828681.html
Copyright © 2011-2022 走看看