1. 概述

require.js是各种网络APP中非常常见的JS依赖库,它其实不仅仅是个模块加载器那么简单。它背后蕴含了一个非常重要的设计,也就是JS模块化编程。模块化是任何一个编程语言都会支持的设计,通过模块化能够将一个重要的问题拆分成一个个小的问题,并且模块与模块之间不关联(或者弱关联),减小的程序的开发难度。

最开始的时候,每个JS框架都会设计自己的模块加载方案,每次使用不同的JS的框架就得理解不同的模块加载方案。后来随着require.js的推广和使用,就逐渐形成了AMD(The Asynchronous Module Definition),也就是"异步模块加载机制"。这样,如果大家都约定使用同样的模块化规范设计,从一个框架到另外一个框架就没有成本,并且可以互相加载引入。

这里通过一个计算幂运算的例子,详细论述require.js的使用。

2. 详论

AMD模块规范听起来很高大上,但实际上并不是很复杂。模块化设计就是为了方便模块之间交互性,那么接口必然是统一而简约的,我们只要按照约定的规则来使用它即可。

2.1. 定义

模块化设计当然应该先定义一个模块了,这里定义一个乘法函数模块(Multiply.js):

//自定义模块
define(function () {
"use strict"; var Multiply = function(x, y) { 
return x * y;
}; return Multiply;
})

再定义一个数学函数库模块,当然里面只有一个求幂运算函数(MyMath.js):

//自定义模块
define(["./Multiply"], function(Multiply){
"use strict"; function MyMath(){
} MyMath.prototype.pow = function(base, exponent){
let result = 1;
for(let i = 0; i < exponent; i++){
result = Multiply(result, base);
}
return result;
} var myMath = new MyMath();
return myMath;
})

这里两个例子说明了定义模块是通过define方法定义模块的,其中第一个参数可以是一个数组,指明该模块的依赖:

define([tools], function(){});

2.2. 调用

接下来在主函数(main.js)中调用自定义的数学函数库模块:

//函数立即执行,避免污染全局作用域
(function(){
"use strict"; require.config({
paths: {
"jquery": "./3rdParty/jquery-3.5.1",
"MyMath": "./MyMath"
}
}); //调用模块
require(["jquery", "MyMath"],function($, MyMath){
$("button").click(function () {
var base = $("#base").val();
var exponent = $("#exponent").val();
var result = MyMath.pow(base, exponent);
$("#result").val(result);
});
}) })()

这里加载了JQuery库,因为JQuery库是按照AMD标准规范来构建的,所以可以通过require.js来引入。

require.config是用来配置导入的库文件,用来给模块定义配置真正的路径和简短的名称。

通过require方法去加载自定义的数学库模块和JQuery模块,其中第一个参数定义了需要加载的模块;第二个参数则是加载成功之后的回调函数:

require(['modules'], callback);

2.3. 入口

接下来就是定义HTML页面脚本加载的入口了(RequireJSTest.html):

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<title>RequireJS-AMD规范</title>
</head> <body>
<div>
<div>
<label>求幂运算:</label>
</div> <div>
<label>底数:</label>
<input type="number" value="2" id = "base">
</div> <div>
<label>指数:</label>
<input type="number" value="8" id = "exponent">
</div> <div>
<button type="button">结果为:</button>
<input type="number" id = "result">
</div>
</div>
<script src="3rdParty/require.js" data-main="main"></script>
</body> </html>

其中,<script src="3rdParty/require.js" data-main="main"></script> 这句代码定义了脚本的加载入口,src当然是require.js的源代码,而data-main则会默认的将dota-main指定的js路径为根路径。

关于dota-main属性,mozilla.org的具体说明如下:data-* 全局属性 是一类被称为自定义数据属性的属性,它赋予我们在所有 HTML 元素上嵌入自定义数据属性的能力,并可以通过脚本在 HTML 与 DOM 表现之间进行专有数据的交换。

这里还要注意的是AMD规范的脚本加载是异步的,同时会预先加载所有的依赖模块的脚本直到完成,再进入本脚本内容。

3. 结果

运行结果如下,输入底数和指数后,点击按钮就会生成正确的结果:

4. 参考

  1. 【第67期】ES6 系列之模块加载方案
  2. Javascript模块化编程(三):require.js的用法
  3. JavaScript的模块化编程

JS模块化编程规范1——require.js的更多相关文章

  1. Javascript模块化编程之路——(require.js)

    转自:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html Javascript模块化编程(一):模块的写法 随着网站逐渐变成&q ...

  2. require.js实现js模块化编程(一)

    1.认识require.js: 官方文档:http://requirejs.org/RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一.最新版本的Requ ...

  3. 初步理解require.js模块化编程

    初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员R ...

  4. require.js实现js模块化编程(二):RequireJS Optimizer

    require.js实现js模块化编程(二):RequireJS Optimizer 这一节,我们主要学习一下require.js所提供的一个优化工具r.js的用法. 1.认识RequireJS Op ...

  5. JS模块化编程(四)--require应用

    获取&使用require.js 下载最新版的Require.JS.下载之后,把它放在项目的脚本文件夹下,比如 js 文件夹下,项目结构看上去应该是: 要充分使用Require.JS,将html ...

  6. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  7. js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    先回答我:为什么模块很重要? 答:因为有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块.但是,这样做有一个前提,那就是大家必须以同样的方式编写模块,否则你有你的写法,我有我的写 ...

  8. 好文推荐系列-------(5)js模块化编程

    本文主要来源于阮一峰的<Javascript模块化编程>系列文章整合,原文地址:http://www.ruanyifeng.com/blog/2012/10/javascript_modu ...

  9. JS模块化编程(二)

    背景 我们常在页面引用js遇到下面情况 <script src="1.js"></script> <script src="2.js&quo ...

  10. [转]js模块化编程之彻底弄懂CommonJS和AMD/CMD!

    原文: https://www.cnblogs.com/chenguangliang/p/5856701.html ------------------------------------------ ...

随机推荐

  1. FragmentStatePagerAdapter

    public abstract class FragmentStatePagerAdapter extends PagerAdapter java.lang.Object    ↳ android.s ...

  2. Perceptual Losses 风格迁移论文复现小记

    看了一篇李飞飞组的论文 Perceptual Losses for Real-Time Style Transfer and Super-Resolution. 论文地址为:https://arxiv ...

  3. Python 日期和时间处理教程:datetime 模块的使用

    Python 中的日期不是独立的数据类型,但我们可以导入一个名为 datetime 的模块来使用日期作为日期对象. 示例:导入 datetime 模块并显示当前日期: import datetime ...

  4. 题解 UVA10299

    前言 数学符号约定: \(a\).\(b\).\(m\).\(n\).\(x\).\(y\):任意一个正整数. \(p\):任意一个质数. \(d\):一个数的任意一个因子. \(\varphi(n) ...

  5. C语言求100以内的全部素数,每行输出10个。素数就是只能被1和自身整除的正整数,1不是素数,2是素数。要求定义和调用函数prime(m)判断m是否为素数,当m为素数时返回1,否则返回0。

    /* 开发者:慢蜗牛 开发时间:2020.5.28 程序功能:求100以内的素数 */ #include<stdio.h> int prime(int m); int prime(int ...

  6. 深入了解MD5加密技术及其应用与局限

    一.MD5简介 MD5(Message Digest Algorithm 5)是一种单向散列函数,由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)于1991年发明.它主要用于将任 ...

  7. Aiganize组局小程序开发手册

    1. 开发阶段概述: 第一阶段: 针对组局和参局的产品功能落地完善小程序, 修改前端界面,去除冗余, 完善数据库设计 完善组局参局的功能 让每个用户能参与组局大厅的组局 让用户能申请为组局者发起组局, ...

  8. 我理解的null和“ “,希望大家给予更正。

    我认为null是零的意思,就是没有任何的东西,比如说文件的读取中,没有任何的东西就是null,刚刚用new String创建的String里面有一个引用,所以它不为null,如果用String h=& ...

  9. macOS 苹果电脑双面打印单面打印PDF设置

    苹果的打印服务分为两个部分,一个是应用层另一个是系统层. 其中双面打印或单面打印统一在系统层面设置,下面我分别截图示意wps pdf和福昕pdf两款软件设置双面打印. 1.WPS PDF 在完成方式中 ...

  10. PyTorch 中自定义数据集的读取方法

    显然我们在学习深度学习时,不能只局限于通过使用官方提供的MNSIT.CIFAR-10.CIFAR-100这样的数据集,很多时候我们还是需要根据自己遇到的实际问题自己去搜集数据,然后制作数据集(收集数据 ...