前端开发实战基础——模块

文章目录

    • 概要
      • 模块标识符
      • 模块依赖
      • 模块加载
      • 入口
    • CommonJS
      • 语法
      • 单例
    • AMD
      • 语法
    • UMD
      • 核心语法
    • ES6模块化
      • 模块标签及定义
      • 模块导出和导入
        • 命名导出和导入
        • 默认导出和导入
        • 命名导出和默认导出混用
      • 模块行为
    • 小结

概要

模块化,就是将代码拆分成独立的块,各自在代码块中实现各自逻辑,同时自行决定引入外部代码,和决定对外暴露一些可以对外提供的特性功能

模块化包含下面特征:标识符、依赖、加载、入口等,下面具体说明一下

模块标识符

模块化标识符是所有模块通用的概念。模块系统可以通过一个标识符来代表一个模块,然后在需要调用的地方,通过这个标识符来引用对应的模块

标识符可以是一个字符串,在原生的实现的模块系统中可能是模块文件的实际路径。有些模块化系统支持明确声明模块的标识。不管哪种方式,完备的模块化系统一定不存在模块标识符冲突问题

模块依赖

模块化系统核心是管理依赖指定依赖的模块与周围的环境达成一种契约。本地模块向模块化系统声明一处外部模块(依赖),这些外部模块对于当前模块的运行是必需的。模块系统会检查这些依赖,进而保证外部模块能够被正确加载到本地模块,完成初始化。

每个模块都会有一个唯一的标识符关联,用于检索模块。这个标识符通常是模块本身内部声明的命名空间路径的字符串或者在某些系统是文件的路径

模块加载

加载模块的概念是由模块依赖产生的。当一个外部模块被指定为依赖的时候,本地模块在准备执行时,外部模块已经完成初始化,等着被执行。
在浏览器中,加载模块涉及其中代码执行,但必须在所有依赖都加载并执行之后。

入口

相互依赖的模块必须指定一个入口,这个也是代码执行的起点。因为JavaScript是顺序执行的,并且是单线程,所有代码必须有执行的起点

在ES6之前,出现需要的模块化解决方案,现在具体说明一下

CommonJS

CommonJS 规范,用于Node.js 服务端,实现模块化代码组织,其语法不能直接在浏览器运行。

语法

CommonJS 模块定义需要使用require()指定依赖,而使用exports 对象定义自己公共的API

请求模块也会加载相应的模块,而把模块赋值给变量也非常常见,但赋值不是必须的,调用require() 意味着模块会原封不动的加载进来

下面代码展示

//moduleA 文件
var moduleB = require("./moduleB");
module.exports = {
stuff: moduleB.doStuff;
}//moduleC 引入moduleA 
var moduleA = require("./moduleA");
moduleA.stuff;

moduleA 通过使用模块定义相对路径指定自己对moduleB的依赖

在 moudleC 文件,通过require 引入 moduleA ,并给它起一个别名 moduleA。直接通过moduleA.stuff 便可以访问 moudleA 的staff.

moudle.exports 对象非常灵活,有多种使用方式。如果只想导出一个实体,可以直接module.exports 赋值

在这里插入图片描述
通过上面的语法,整个模块就导出一个字符串,可以通过下面的方式使用:
在这里插入图片描述

单例

模块加载是单例的,无论在一个模块require() 中被引用多少次模块只会被加载一次,模块第一次请求加载后会被缓存,再次请求模块,都只是取得模块的缓存,如下面的代码所示
在这里插入图片描述

AMD

CommonJS 以服务端为目标环境,能够同步地一次性所有依赖都加载到内存,无需考虑异步加载的问题。

异步加载模块定义,AMD( asynchronous Module Definition) 则以浏览器为执行环境,需要考虑网络延迟问题,因此实现了按需依次加载依赖,并在加载完成后,立即执行依赖模块

ADM模块实现的核心是用函数包装模块定义。这样防止声明全局变量,并允许加载器库控制何时加载

包装模块函数是全局的define 的参数,它是由AMD加载器库的实现定义的

语法

AMD 模块可以使用字符串指定自己的依赖,代码示例如下

/ID为’ moduleA'的模块定义。moduleA依赖moduleB
//moduleB会异步加载
define('moduleA',['moduleB'].function(moduleB) [return (stuff: moduleB.doStuff(););
});

AMD 也支持require 和 exports 对象,通过他们可以在AMD模块工厂函数内部定义CommonJS 风格的模块。
在这里插入图片描述

动态依赖也是通过这种方式支持的:
在这里插入图片描述

UMD

为了统一CommonJs 和 AMD 生态系统,通用模块定义(UMD,universal module definition)规范应运而生。

UMD 创建了两个系统都可以使用的模块代码,本质上UMD会检测依赖使用了哪种系统,然后进行适配,并把所有的逻辑包装在一个立即调用的函数表达式中。

核心语法

在这里插入图片描述

ES6模块化

ES6 引入了模块规范,使得浏览器支持原生的模块化加载。
下面对 ES6模块规范进行说明

模块标签及定义

浏览器中,我们可以通过在 script 标签中 加入 type=“module” 的属性,告诉浏览器这一块代码应该作为哦模块执行,而不是作为传统的脚本执行。模块可以嵌入网页中,也可以作为外部文件引入。

<script type="module">
// 模块代码
</script>
<script type="module src="path/to/myModule,js"></script>

与传统的脚本不同,所有模块都会想 script defer 加载的 脚本一样按顺序执行。 当解析到 script type="moudle" 标签后会立即下载模块文件,但执行会延迟到文档解析完成,因此不会阻塞文档解析

下面演示模块执行顺序
在这里插入图片描述

模块导出和导入

ES6模块导出和CommonJs非常相似,通过export 关键字导出模块,ES6支持两种导出,命名导出和默认导出,不同的导出方式的引入方式不同。

命名导出和导入

命名导出,可以定义一个变量,然后通过export 将变量导出,例子如下
在这里插入图片描述
或者下面的导出也是可以的
在这里插入图片描述

导入方式如下:
通过命名导出的,要使用 import 关键字 和{ }

import {foo} from "./moudleA"
默认导出和导入

默认导出如下:
使用export default 导出foo

const foo = foo'
export default foo

或者使用下面的方式也是可以的

const foo = 'foo'
//等同于export default foo:
export {foo as default };

导入方式如下

import foo from "./foo.js";
//或者使用 as
import {default as foo} from "./foo.js"

如果一个模块有多个命名空间
比如以下

const foo="foo".bar = "bar",baz = "baz"
export {foo,bar,baz}

我们可以使用 * 一次性全部导入,然后通过as 指定一个别名,通过别名访问对应的命名空间。

import * as Foo from "./foo.js"
console.log(Foo.foo)//"foo"
命名导出和默认导出混用

如果一个模块使用了命名空间和默认导出
如下面的示例

export const foo = "foo"
export default const baz ="baz"

导出

import baz,{foo} from "./foo.js"

模块行为

ES6借鉴了 CommonJS 和AMD 很多优秀的特性,下面简单列举一些

  • 模块代码只在加载后执行
  • 模块只加载一次
  • 模块式单例的
  • 模块可以定义公共接口,其他模块可以基于这个公共接口观察和交互
  • 模块可以请求加载其他模块
  • 支持循环依赖

除此之外,ES6还增加自己的特性

  • ES6模块在严格模式执行
  • ES6不共享命名空间
  • 模块顶级this 是undefined
  • 模块定义的var 不会添加到window
  • ES6模块式异步加载和执行的

小结

  • CommonJS 用于Node 服务端模块化,采取module.exports 对象 + require 导出导入
  • AMD 异步加载模块化,可以用于浏览器解决脚本异步加载,通过全局的define 函数定义模块
  • UMD 实现了AMD 和CommonJs的集成,本质上也是检测并适配。
  • ES6 增加了模块化方案,采用export + import 导出导入,还可以支持默认导出

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

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

相关文章

Android Jetpack Compose之底部导航栏的实现

目录 1.概述2. 效果展示3. 代码实现3.1 定义底部导航栏的tab项3.2 整体页面架构搭建3.3 底部导航栏的实现3.4 所有代码 4.总结 1.概述 写过一段Android jetpack compose 界面的小伙伴应该都用过Compose的脚手架Scaffold&#xff0c;利用它我们可以很快的实现一个现代APP的主流…

MySQL窗口函数--lead()函数

lead()函数&#xff1a; 查询当前行向下偏移n行对应的结果 该函数有三个参数&#xff1a;第一个为待查询的参数列名&#xff0c;第二个为向下偏移的位数&#xff0c;第三个参数为超出最下面边界的默认值。 如下代码&#xff1a; 查询向下偏移 2 位的年龄 SELECT user_id,user…

路灯哪个牌子好?2024年大路灯推荐合集

经常晚上学习的学生党、加班加点的打工人以及三更半夜备考的考公考研人士都看过来&#xff01;你是否经常会出现眼睛酸痛、干涩、疲劳的情况&#xff0c;并且注意力不集中&#xff0c;长期下来不仅工作学习效率低&#xff0c;而且视力也受到了影响。这是一大部分原因是因为长期…

前端通过nginx,访问一个文件夹里面的全部数据,nginx 咋配置

目录 1 问题2 实现 1 问题 前端通过nginx,访问一个文件夹里面的全部数据&#xff0c;nginx 咋配置 2 实现 location /logs {alias /mnt/www/logs/;autoindex on; }

配置了静态ip地址后,通过ssh连接到虚拟机比较慢

配置了静态ip地址后&#xff0c;通过ssh连接到虚拟机比较慢 [rootlocalhost ~]# vim /etc/ssh/sshd_config#快速方式找到UsePAM&#xff0c;输入“/UsePAM”而后回车&#xff0c;直接跳到UsePAM位置&#xff0c;将yes修改成no #键盘输入" i "开始编译 #"Esc&qu…

Redis核心技术与实战【学习笔记】 - 9.如何避免单线程模型的阻塞

概述 Redis 被广泛应用的原因是因为它支持高性能访问。所以&#xff0c;我们要重视所有可能影响 Redis 性能的因素&#xff08;如命令操作、系统配置、关键机制、硬件配置等&#xff09;。 影响 Redis 性能的 5 大方面的潜在因素分别是&#xff1a; Redis 内部的阻塞式操作C…

二叉树-堆应用(1)

目录 堆排序 整体思路 代码实现 Q1建大堆/小堆 Q2数据个数和下标 TopK问题 整体思路 代码实现 Q1造数据CreateData Q2建大堆/小堆 建堆的两种方法这里会用到前面的向上/向下调整/交换函数。向上调整&向下调整算法-CSDN博客 堆排序 整体思路 建堆&#xff08;直…

【经典项目】Java小游戏 —— 会说话的汤姆猫

一、游戏回顾 【预期效果】 【玩法介绍】 1、 和它说话&#xff0c;它将用有趣的声音重复你的话。 2、打它的头&#xff0c;它会装成被打的样子&#xff0c;连续打还会晕倒&#xff1b;抚摸肚子&#xff0c;它会打呼噜&#xff1b;打肚子&#xff0c;它会装肚子疼&#xff1b…

AVR 328pb定时器0基本介绍和使用

AVR 328pb定时器0基本介绍和使用 &#x1f4cc;参考ATmega328PB文档.&#x1f4cd;结合参考同架构lgt8f328p中文文档&#xff1a;http://www.prodesign.com.cn/wp-content/uploads/2023/03/LGT8FX8P_databook_v1.0.4.pdf &#x1f4d7;定时器0基本功能描述 两个独立的输出比较…

记一次java项目本地正常执行,打完包之后执行发现没有对应的类或配置的问题

1、起因 线上有个spark的任务出了问题&#xff08;该任务是通过sparkstreaming读取kafka中的数据&#xff0c;处理完之后推到es中&#xff09;&#xff0c;问题出在kafka中数据是有更新的&#xff0c;但是es中的对应索引中的数据却只更新到月初&#xff0c;因此我需要排查处理…

JavaSE-项目小结-IP归属地查询(本地IP地址库)

一、项目介绍 1. 背景 IP地址是网络通信中的重要标识&#xff0c;通过分析IP地址的归属地信息&#xff0c;可以帮助我们了解访问来源、用户行为和网络安全等关键信息。例如应用于网站访问日志分析&#xff1a;通过分析访问日志中的IP地址&#xff0c;了解网站访问者的地理位置分…

Linux进程通信基础

前要&#xff1a;本节内容主要是管道和共享内存块&#xff0c;而且我们需要明白我们所讲的进程通信本质是为了在内存中传递数据&#xff08;看到同一份资源&#xff09;。 而实际上&#xff0c;我们也可以通过磁盘传递数据&#xff0c;但是为什么不这么做呢&#xff1f;很简单&…