模块化:AMD规范

news/2024/5/16 16:08:13/文章来源:https://blog.csdn.net/weixin_43524214/article/details/127146150

        之前在《模块化:CommonJS规范》文中对CMD规范进行了介绍,并给出了服务端和浏览器端基于CommonJS模块化规范构建项目和模块化开发的示例demo。严格来讲,CommonJS这种模块化规范更加适用于服务器端编程,由于是同步的加载方式,并不十分适合浏览器端项目开发。

        而此处介绍的AMD(Asynchronous Module Definition)-异步模块定义的规范——简称AMD规范,则采用异步方式加载模块,不会阻塞浏览器展示页面时,dom构建、css渲染等其它任务,模块内部的内容则采用同步加载方式,加载完成之后会立即执行主模块中定义的回调函数,真正启动web应用程序。

目录

AMD:基本语法

模块定义语法

模块引入语法

非AMD的传统模块化开发模式

早期模块化开发:IIFE模式+外部依赖引入

 早期模块化开发:优缺点

AMD模块化开发模式

示例demo构建与测试

AMD模块化开发:AMD模块引入

AMD模块化开发:非AMD模块引入


AMD:基本语法

        AMD作为一种模块化规范,有其对应的第三方库作为具体实现,最常用的就是RequireJS。也就是说,AMD规范的应用,需要借助RequireJS第三方库才能实现,点击此处,可访问其官网。

模块定义语法

        AMD模块定义通过define语句实现,通常在开发过程中,基于define语法定义的模块可分为两类,

        ①没有依赖的模块,其语法如下,回调函数的内容即为自定义的模块的内容,

	define(function(){//todo:定义模块内容        //返回模块对象return 模块;})

        ②定义有依赖的模块,其语法为如下,

define(['module1',...,'modulen'],function(param)	{//todo:定义模块内容    //返回模块对象return 模块;
});

          其中:

                [1] 参数1:数组形式的字符串,显示声明要注入的若干依赖模块;
                [2] 参数2:param-回调函数,在模块加载之后会立即执行。

模块引入语法

        通常是在主模块开头部分,会使用RequireJS库提供的requirejs.config()、requirejs()接口分别实现子模块的路径配置与非AMD模块到AMD模块的映射、子模块的加载和主模块内容的定义。

        代码示例及其注释如下,

  //配置子模块及其路径requirejs.config({baseUrl: 'js', //相对根目录的路劲//默认相对于当前main.js主模块的相对路径paths: {dataService:'./modules/dataService',alert:'./modules/alert',jquery: './libs/jquery-3.6.1', //jquery默认支持amd规范angular: './libs/angular', //angular.js-非amd规范的模块},shim:{//配置非amd规范的js脚本库-将当前非amd文件规范化为AMD模块angular: {exports:'angular',}}});//引入子模块requirejs(['alert','jquery','angular'],function (alert,$,angular){alert.showMsg();const domTitle = $('#title')[0].innerText;console.log(domTitle);console.log(angular)});

非AMD的传统模块化开发模式

        在出现RequireJS等AMD规范具体实现的第三方库之前,也已经诞生了不少模块化开发的方法,较为经典的就是“基于立即执行函数实现的模块模式开发”,也即:IIFE匿名闭包升级版本。在正式介绍AMD规范之前,有必要介绍一下早期的“模块模式”实现的模块化开发,及其缺点所在。

早期模块化开发:IIFE模式+外部依赖引入

        ①创建一个项目,其基本结构如下,其中:app.js为主模块、alert.js和dataService.js为子模块,index.html为将要引入主模块app.js的主页面。

        ②编写主模块和子模块的内容,

         ③在index.html主文件中引入app.js主模块,

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
</body>
<!--引入依赖模块-->
<script src="js/dataService.js"></script>
<script src="js/alert.js"></script>
<!--引入主模块-->
<script src="app.js"></script>
</html>

                最终显示的内容如下,

 早期模块化开发:优缺点

                这种早期的借助立即执行函数实现的IIFE+外部依赖的模块化开发方式,其实就是现代模块化开发规范,包括ES6模块化规范的基石。其最大的优点就是:纯原生框架,无需借助任何第三方框架即可实现项目的模块化构建;其缺点是:需要在index.html主文件中引入主模块,以及主模块所依赖的所有的子模块,那么,在初始化index.html页面时,就需要发送若干次js文件的请求;并且还要保证子模块的引入顺序,否则就会出错。 对于大型项目来说,后期整体会变得越来越臃肿,甚至难以维护,因为模块之间的关系可能复杂到无法理解。

AMD模块化开发模式

        前面已经提到,AMD只是一种开发规范,而RequireJS第三方JavaScript脚本库对其进行了实现。因此,Require.js作为一个异步的JavaScript模块加载器,下面的示例程序,必须要引入这个js脚本,可到官网进行下载:RequireJS。

示例demo构建与测试

        ①搭建如下的项目框架,基本结构如下图。

                其中:js/libs-用来存放所依赖的第三方js脚本库;js/modules-用来存放自定义的AMD子模块;main.js-是Web应用程序的子模块;index.html-是Web应用程序的主页面。

         ②定义主模块和子模块,如下图所示,

                 其中,主模块main.js的内容如下,

//主模块
(function (){//配置子模块及其路径requirejs.config({baseUrl: 'js', //相对根目录的路劲//默认相对于当前main.js主模块的相对路径paths: {//引入自定义模块dataService:'./modules/dataService',alert:'./modules/alert',//引入主模块jquery: './libs/jquery-3.6.1'}});//引入子模块requirejs(['alert','jquery'],function (alert,$){alert.showMsg();const domTitle = $('#title')[0].innerText;console.log(domTitle);});
})();

        ③下载并在index.html文件中引入Require.js依赖库、主模块main.js,

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>AMD规范</title><!-- 引入子模块--><script data-main="js/main.js" src="js/libs/require.js"></script>
</head>
<body><div id="title">AMD规范实现</div>
</body>
</html>

        ④最终的实现效果如下,

AMD模块化开发:AMD模块引入

        AMD模块化开发方式遇到的首要问题就是,如何引入自定义的、或者是第三方AMD子模块?

        一般都是通过require.config()接口来实现的,示例代码如下,

//主模块
(function (){//配置子模块及其路径requirejs.config({baseUrl: 'js', //相对根目录的路劲//默认相对于当前main.js主模块的相对路径paths: {dataService:'./modules/dataService',alert:'./modules/alert',jquery: './libs/jquery-3.6.1', //jquery默认支持amd规范},});//引入子模块requirejs(['alert','jquery'],function (alert,$){alert.showMsg();const domTitle = $('#title')[0].innerText;console.log(domTitle);});
})();

        上面的代码部分,baseUrl定义了子模块所在的根路径,这个路径是相对于项目的根路径来讲的;而paths参数部分,则对应子模块的配置信息。主要是子模块的模块id名称、与相对于baseUrl基路径的相对路径配置。

        配置完毕之后,就可以在requirejs()接口中的第1个参数未知,加载需要的子模块,并将其作为回调函数的参数,就可以使用了。

AMD模块化开发:非AMD模块引入

        在实际的开发中,我们遇到的有些第三方模块可能不是遵循AMD规范的,这时候就可以通过require.config()接口的shim参数将其映射为AMD模块。示例代码如下,将angular.js-非AMD第三方模块映射为AMD模块,并进行使用.

//主模块
(function (){//配置子模块及其路径requirejs.config({baseUrl: 'js', //相对根目录的路劲//默认相对于当前main.js主模块的相对路径paths: {dataService:'./modules/dataService',alert:'./modules/alert',jquery: './libs/jquery-3.6.1', //jquery默认支持amd规范angular: './libs/angular', //angular.js-非amd规范的模块},shim:{//配置非amd规范的js脚本库-将当前非amd文件规范化为AMD模块angular: {exports:'angular',}}});//引入子模块requirejs(['alert','jquery','angular'],function (alert,$,angular){alert.showMsg();const domTitle = $('#title')[0].innerText;console.log(domTitle);console.log(angular)});
})();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_17625.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch_02_ElastisSearch的基本语法使用

系列文章目录 文章目录系列文章目录前言一、基本语法使用1.1 _search接口获取所有数据1.2 文档操作插入文档查询文档修改文档查询所有的索引和查询所有的数据删除文档二、各种各样的查询条件2.1 查询所有2.2 值匹配和输出结构按price倒序输出2.3 仅输出需要的数量2.4 仅输出需要…

论文(一):Revisiting multiple instance neural networks

Revisiting multiple instance neural networks 回顾多示例神经网络 1、Abstract ​ 近年来&#xff0c;神经网络和多实例学习(MIL)都是人工智能相关研究领域的热门课题。深度神经网络在监督学习问题上取得了巨大的成功&#xff0c;而MIL作为一种典型的弱监督学习方法&#…

J2EE 知识点总结_上

J2EE 知识点总结_上基础概念数组选择排序 &#xff1a;交换排序 &#xff1a;插入排序面向对象重载&#xff08;**Overload**&#xff09;的概念构造器的作用&#xff1a;JavaBean多态性instanceof 操作符操作符与equals方法&#xff1a;包装类(Wrapper)的使用垃圾回收机制关键…

RLE算法机制、缺点及哈夫曼算法和莫尔斯编码

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 目录 一、RLE算法机制 二、RLE算法的缺点 三、哈夫曼算法和莫尔斯编码 一、RLE算法机制 对 AAAAAABBCDDEEEEEF 这17个半角字符的文件&#xff08;文本文件&#xff09;进行压缩。虽然这些文字没有什么实际意义&#xff0…

Spring源码分析(三)Bean生命周期源码解析1:扫描生成BeanDefinition

Spring最重要的功能就是帮助程序员创建对象&#xff08;也就是IOC&#xff09;&#xff0c;而启动Spring就是为创建Bean对象做准备&#xff0c;如果先分析Spring启动过程的源码&#xff0c;会比较难理解&#xff0c;因为你可能不知道为什么要做这些准备动作&#xff0c;所以我们…

Shiro知识总结二

3. 与 Spring Boot 整合 3.1 框架整合 依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>o…

java基于springboot+vue+nodejs的高校学生健康档案管理系统 element

随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代,高校学生健康档案管理系统就是信息时代变革中的产物之一。 在经济快速发展的带…

快速玩转Yolov5目标检测—没有好的显卡也能玩(二)

上篇 快速玩转Yolov5目标检测—没有好的显卡也能玩&#xff08;一&#xff09; 已经将YoloV5在我的笔记本电脑上快速跑起来了&#xff0c;因为电脑显卡一般&#xff0c;所以运行的CPU版本&#xff0c;从推理结果来看&#xff0c;耗时还是蛮高的&#xff0c;如下图&#xff0c;…

03 NLP-神经网络基础常识复习2-计算图(乘法节点,分支节点,Repeat节点,Sum节点,MatMul节点)

下面&#xff0c;我们将研究误差反向传播法。不过在此之前&#xff0c;作为准备工作&#xff0c;我们先来介绍一下计算图的相关内容。计算图是计算过程的图形表示。所示为计算图的一个例子 计算图通过节点和箭头来表示。这里&#xff0c;“”表示加法&#xff0c;变量x和y写在各…

【流放之路闪电打击开荒攻略】

重点1&#xff1a;每次攻击杀1群白怪 重点2&#xff1a;地图区域等级-4《角色等级《地图区域等级2 重点3&#xff1a;非boss战斗不死亡 重点4&#xff1a;对下阶段成长有目标&#xff0c;搜集装备 国际服网址 G&#xff08;green&#xff09;R&#xff08;red&#xff09;B&am…

SSTI基础知识

我们用如下环境进行讲解(flask-jinja2):from flask import Flask from flask import render_template from flask import request from flask import render_template_string app = Flask(__name__) @app.route(/) def index():code = request.args.get(id)template = <h3&…

【Pandas总结】第九节 Pandas_累计与分组 pd.groupby()

文章目录一、数据准备二、累计值计算2.1 df.describe()2.2 常用统计值三、分组 pd.groupby()四、更多的使用方法aggregate(),filter(),transform(),apply()4.1 aggregate()4.2 filter()4.3 transform()4.4 apply()在对较大数据进行分析时&#xff0c;有一项最基本的工作就是&am…

2022-09-18-事务机制与锁

事务机制与锁 事务ACID特性(4大特性):原子性;一致性;隔离性;持久性。事务隔离性(四大隔离级别):读未提交;读已提交;可重复读;串行。脏读:读到了别的事务还没有提交,可能随时会被回滚掉的,有可能不存在的数据,这叫做脏读。 可重复读:我第一次查到的数据,我之后…

【选择】选择排序、堆排序(大根堆【升序】,小根堆【降序】)

简单选择排序 思想&#xff1a;默认0号位&#xff0c;定义为min&#xff0c;再从第二位起&#xff0c;遍历所有&#xff0c;找到一个更小的&#xff0c;把下标赋给min&#xff0c;遍历结束&#xff0c;如果当前i下标的值不是min&#xff0c;则说明min更新&#xff0c;有更小的…

【牛客-算法】 NC48 在旋转过的有序数组中寻找目标值

文章目录&#x1f6a9; 前言1.题目描述2.算法设计思路3.算法实现bug记录&#x1f9ed; 遇到问题&#xff08;可跳过&#xff09;&#x1f33b; 写在前面我最初的通过代码&#xff08;C语言&#xff09;4.运行结果5.小结&#x1f525; 该专栏作为算法题笔记&#xff0c;记录算法…

Bert在fine-tune训练时的技巧:①冻结部分层参数、②weight-decay (L2正则化)、③warmup_proportion、④

作为一个NLPer&#xff0c;bert应该是会经常用到的一个模型了。但bert可调参数很多&#xff0c;一些技巧也很多&#xff0c;比如加上weight-decay, layer初始化、冻结参数、只优化部分层参数等等&#xff0c;方法太多了&#xff0c;每次都会纠结该怎么样去finetune&#xff0c;…

打印数组的所有子集

打印数组的所有子集 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;打印数组的所有子集 CSDN&#xff1a;打印数组的所有子集 无重复值情况 题目描述见: LeetCode 78. Subsets 主要思路 定义递归函数 void p(int[] arr, int i, LinkedList<Integer…

【数据结构与算法】深度理解队列(上)

✨hello&#xff0c;进来的小伙伴们&#xff0c;你们好耶&#xff01;✨ &#x1f68e;&#x1f68e;系列专栏&#xff1a;【数据结构与算法】 &#x1f680;&#x1f680;本篇内容:队列从0到1的学习&#xff01; ⛵⛵作者简介&#xff1a;一名双非本科大三在读的科班Java编程小…

11-二叉树-删除

delete(ElementType e)&#xff1a;删除某个值为 e 的结点。实现方法有多种。 按添加结点的规则&#xff0c;小于根结点的放在左边&#xff0c;大于等于根结点的放在右边。b 小于 c 中任意一个子结点&#xff0c;只能放在 c 中最小的一个结点 e 的左子结点下。 除 e 外&#x…

Git基础操作

拉取代码直接clone,复制远程仓库文件夹 git clone git@gitee.com:chen-LinQiang/my-notes.git 在已有仓库文件夹中拉代码 # 初始化 git init # 关联远程仓库 git remote add origin git@gitee.com:chen-LinQiang/my-notes.git # 切换到本地主分支 git checkout master # 若报错…