JavaScript模块化

什么是JavaScript的模块化?

JavaScript的模块化是指将代码分割成独立的、可重用的模块,每个模块具有自己的功能和作用,可以单独进行开发、测试和维护。不同的目的是提升代码的可维护性、可复用性和可扩展性,同时避免不同模块间的命名冲突和依赖问题。

在早期的JavaScript中,所有的代码都被写在同一个文件中,这样会导致以下问题:

  • 全局命名污染:所有的变量和函数都在全局作用域中,可能导致命名冲突。
  • 代码复制困难:如果需要在不同的项目或模块中复制相同的功能,需要手动复制代码,维护起来非常困难。
  • 代码组织差:代码越来越多,逻辑难以分割,导致可维护性差。

为了解决这些问题,JavaScript社区提供了 CommonJS AMD。

CommonJS :

  • 为了在服务器端(Node.js环境)实现自定义,CommonJS标准应运而生。
  • 使用require()导入模块,module.exports导出模块,解决了代码组织和模块依赖问题。
  • CommonJS的设计主要面向同步加载,适用于服务器端。

AMD :

  • AMD(如RequireJS)在浏览器环境中解决了优先问题。
  • 它支持异步加载模块,避免了浏览器中模块过多导致的性能问题。
  • AMD允许第四个加载模块,并且不要求模块按照顺序加载,这在浏览器中尤其有用。

后面官方终于开始做为,在ECMAScript 6(ES6)标准中,JavaScript语言初步支持了标准,提供了importexport关键字。

ES模块化:

  • 静态分析:模块的依赖关系可以在编译时解析,优化性能。
  • 支持异步加载:通过动态import()可以辅助加载模块。
  • 模块作用域:每个模块都有自己的作用域,避免了全局作用域污染。

ES模块使用方法

1. 具名导出

导出变量、函数、类

// math.js// 导出变量
export const PI = 3.14159;// 导出函数
export function add(a, b) {return a + b;
}// 导出类
export class Calculator {multiply(a, b) {return a * b;}
}

导入变量、函数、类

// main.js
import { PI, add, Calculator } from './math.js';console.log(PI); // 3.14159
console.log(add(2, 3)); // 5const calc = new Calculator();
console.log(calc.multiply(4, 5)); // 20

2. 默认导出 export default

默认导出时,导入的名称可以自定义。

导出

// logger.js
export default function logMessage(message) {console.log("Log:", message);
}

导入

// main.js
import log from './logger.js';log("Hello, World!"); // Log: Hello, World!

3. 组合导出(命名空间)

导出

// utils.js
const name = "JavaScript";
function greet() {return "Hello, " + name;
}
export { name, greet };

导入

// main.js
import * as utils from './utils.js';console.log(utils.name); // JavaScript
console.log(utils.greet()); // Hello, JavaScript// 代码说明
// import * as utils from './utils.js' 代码表示如下:
// *:表示导入该模块中所有导出的内容。
// as:表示将所有导入的内容命名为一个单一的对象(即命名空间),这个对象的名字是 utils。
// 你可以通过 utils 对象访问 utils.js 中导出的所有内容。

4. 重新导出

可以从一个模块导入后重新导出,使其变成一个中转模块。

导出

// math.js
// 导出变量
export const PI = 3.14159;// 导出函数
export function add(a, b) {return a + b;
}// 导出类
export class Calculator {multiply(a, b) {return a * b;}
}

重新导出

// mathOperations.js
export { PI, add, Calculator } from './math.js';

导入

// main.js
import { PI, add } from './mathOperations.js';console.log(PI); // 3.14159
console.log(add(10, 20)); // 30

5. 动态导入 import()

import() 动态导入允许在运行时动态加载模块,适用于按需加载或懒加载场景。结合 await 进行异步模块加载。

导出

// math.js
export function add(a, b) {return a + b;
}

导入

// main.js
async function loadMathModule() {const math = await import('./math.js');console.log(math.add(5, 10)); // 15
}
loadMathModule();

6. 浏览器导入

在 HTML 中使用 <script type="module">。代码不会污染全局作用域。浏览器支持 import,不需要 Webpack 等打包工具。

导出

// math.js
export function add(a, b) {return a + b;
}

导入

<!-- index.html -->
<script type="module">import { add } from './math.js';console.log(add(3, 7)); // 10
</script>

7. 在 Node.js 中使用 ES 模块

package.json 中添加

{"type": "module"
}

然后可以在 .mjs 文件中使用 ES 模块语法

// server.mjs
import { createServer } from 'http';const server = createServer((req, res) => {res.end("Hello, ES Modules in Node.js!");
});server.listen(3000, () => {console.log("Server running on http://localhost:3000");
});

什么是 .mjs 文件?

上面提到了 .mjs,那么什么是 .mjs 文件?

.mjs 是 JavaScript 模块文件 的扩展名,表示该文件使用了 ES6 模块化(即 ECMAScript 2015 模块)语法。与传统的 .js 文件不同,.mjs 文件明确告知 Node.js 或其他 JavaScript 环境该文件使用的是 ES 模块规范。

为什么使用 .mjs

  1. 区分 CommonJS 和 ES6 模块:在 Node.js 中,默认的模块系统是 CommonJS,通过 require()module.exports 来加载和导出模块。而 ES6 模块 使用 importexport 语法。为了避免混淆,Node.js 引入了 .mjs 扩展名来明确区分 ES6 模块文件和传统的 CommonJS 文件。

  2. Node.js 与 ES6 模块的兼容性:虽然 ES6 模块是 JavaScript 标准的一部分,但在 Node.js 中直到最近才开始原生支持。为了支持 ES6 模块,Node.js 在 版本 12 及更高版本中引入了 .mjs 文件扩展名。当你在 Node.js 中使用 ES6 模块时,使用 .mjs 扩展名可以让 Node.js 知道该文件使用 ES6 模块化语法。

  3. type 字段:从 Node.js 14 开始,你还可以在 package.json 文件中设置 type 字段来指定整个项目是否使用模块化语法:

    • 如果将 type 设置为 "module",则可以在项目中使用 .js 扩展名来作为 ES6 模块,免去 .mjs 扩展名的要求。
    • 如果不设置或将 type 设置为 "commonjs",则 .js 文件将继续被视为 CommonJS 模块。

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

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

相关文章

【网络编程】Java高并发IO模型深度指南:BIO、NIO、AIO核心解析与实战选型

​​ 目录 一、引言1.1 本文目标与适用场景1.2 什么是IO模型&#xff1f;阻塞 IO 模型非阻塞 IO 模型IO 多路复用模型信号驱动 IO 模型异步 IO 模型 二、基础概念解析2.1 IO模型的分类与核心思想IO模型的分类核心思想分类对比与选择依据技术示意图 2.2 同步 vs 异步 | 阻塞 vs…

基序和纯度分数的计算

以下对这两个概念的详细解释&#xff1a; 基序 纯度分数 PWM矩阵的来源 为什么会有PWM矩阵&#xff1f; 一个特定的转录因子&#xff08;TF&#xff09;的结合位点的基序&#xff08;motif&#xff09;并不是唯一的。实际上&#xff0c;TF结合位点通常具有一定的序列变异性&a…

算法日记11:SC63(离散化)

一、题目 二、题解 法一&#xff1a;前缀和&#xff08;会炸&#xff09; 对于这道题目&#xff0c;我们的第一个朴素想法就是用前缀和来进行简化操作&#xff0c;这个思路非常简单&#xff0c;就是前缀和的标准模板题&#xff0c;代码如下 void solve() {int n,q;cin>&g…

w185客户关系管理系统

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

[STM32 标准库]EXTI应用场景 功能框图 寄存器

一、EXTI 外部中断在嵌入式系统中有广泛的应用场景&#xff0c;如按钮开关控制&#xff0c;传感器触发&#xff0c;通信接口中断等。其原理都差不多&#xff0c;STM32会对外部中断引脚的边沿进行检测&#xff0c;若检测到相应的边沿会触发中断&#xff0c;在中断中做出相应的处…

Windows下怎么安装FFFmpeg呢?

在Windows下使用Open-webui报错&#xff0c;说Couldnt find ffmpeg or avconv,解决open-webui报错Couldn‘t find ffmpeg or avconv-CSDN博客于是尝试解决问题&#xff0c;那么Windows下怎么安装FFFmpeg呢&#xff1f; 尝试了两种方法。 第一种方法pip安装&#xff08;失败&…

Hive on Spark优化

文章目录 第1章集群环境概述1.1 集群配置概述1.2 集群规划概述 第2章 Yarn配置2.1 Yarn配置说明2.2 Yarn配置实操 第3章 Spark配置3.1 Executor配置说明3.1.1 Executor CPU核数配置3.1.2 Executor内存配置3.1.3 Executor个数配置 3.2 Driver配置说明3.3 Spark配置实操 第4章 Hi…

【OMCI实践】ONT上线过程的omci消息(三)

引言 在上一篇文章【OMCI实践】ONT上线过程的omci消息&#xff08;二&#xff09;-CSDN博客中&#xff0c;主要介绍了ONT上线过程的OMCI交互的第一个阶段和第二个阶段omci消息&#xff0c;本篇介绍第二个阶段剩余的OMCI消息涉及到的受管实体&#xff08;ME&#xff09;的属性。…

保姆级教程Docker部署Zookeeper官方镜像

目录 1、安装Docker及可视化工具 2、创建挂载目录 3、运行Zookeeper容器 4、Compose运行Zookeeper容器 5、查看Zookeeper运行状态 6、验证Zookeeper是否正常运行 1、安装Docker及可视化工具 Docker及可视化工具的安装可参考&#xff1a;Ubuntu上安装 Docker及可视化管理…

【数据结构】栈与队列

栈 栈的概念及结构 栈:一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈&…

安全实验作业

一 拓扑图 二 要求 1、R4为ISP&#xff0c;其上只能配置IP地址&#xff1b;R4与其他所有直连设备间均使用共有IP 2、R3-R5-R6-R7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个OSPF环境IP基于172.16.0.0/16划分&#xff1b; 4、所有设备均可访问R4的环回&#x…

e2studio开发RA4M2(6)----GPIO外部中断(IRQ)配置

e2studio开发RA4M2.6--GPIO外部中断&#xff08;IRQ&#xff09;配置 概述视频教学样品申请硬件准备参考程序源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置SWD调试口设置GPIO口配置按键中断配置中断回调函数主程序 概述 GPIO&#xff08;通用输入/输出&a…

排序算法--快速排序

快速排序是高效的排序算法&#xff0c;平均时间复杂度为 O(nlog⁡n)&#xff0c;适合大规模数据排序。 1.挖坑法 2左右指针法 3.前后指针法 // 交换两个元素的值 void swap(int* a, int* b) {int temp *a;*a *b;*b temp; }// 分区函数&#xff0c;返回分区点的索引 int par…

分享|LLM通过D-E-P-S完成长时间与多步骤的任务

《Describe, Explain, Plan and Select: Interactive Planning with Large Language Models Enables Open-World Multi-Task Agents&#xff1f; 描述、解释、计划和选择&#xff1a;使用大型语言模型进行交互式规划&#xff0c;实现开放世界的多任务代理 问题背景&#xff1a;…

chrome浏览器chromedriver下载

chromedriver 下载地址 https://googlechromelabs.github.io/chrome-for-testing/ 上面的链接有和当前发布的chrome浏览器版本相近的chromedriver 实际使用感受 chrome浏览器会自动更新&#xff0c;可以去下载最新的chromedriver使用&#xff0c;自动化中使用新的chromedr…

swagger使用指引

1.swagger介绍 在前后端分离开发中通常由后端程序员设计接口&#xff0c;完成后需要编写接口文档&#xff0c;最后将文档交给前端工程师&#xff0c;前端工程师参考文档进行开发。 可以通过一些工具快速生成接口文档 &#xff0c;本项目通过Swagger生成接口在线文档 。 什么…

一文速览DeepSeek-R1的本地部署——可联网、可实现本地知识库问答:包括671B满血版和各个蒸馏版的部署

前言 自从deepseek R1发布之后「详见《一文速览DeepSeek R1&#xff1a;如何通过纯RL训练大模型的推理能力以比肩甚至超越OpenAI o1(含Kimi K1.5的解读)》」&#xff0c;deepseek便爆火 爆火以后便应了“人红是非多”那句话&#xff0c;不但遭受各种大规模攻击&#xff0c;即便…

低通滤波算法的数学原理和C语言实现

目录 概述 1 原理介绍 1. 1 基本概念 1.2 一阶RC低通滤波器模型 2 C语言完整实现 2.1 滤波器结构体定义 2.2 初始化函数 2.3 滤波计算函数 3 应用示例 3.1 噪声信号滤波 3.2 输出效果对比 3.3 关键参数选择指南 4 性能优化技巧 4.1 定点数优化 4.2 抗溢出处理 …

自研有限元软件与ANSYS精度对比-Bar3D2Node三维杆单元模型-央视大裤衩实例

目录 1、“央视大裤衩”自研有限元软件求解 1.1、选择单元类型 1.2、导入“央视大裤衩”工程 1.3、节点坐标定义 1.4、单元连接关系、材料定义 1.5、约束定义 1.6、外载定义 1.7、矩阵求解 1.8、变形云图展示 1.9、节点位移 1.10、单元应力 1.11、节点支反力 2、“…

Hot100之堆

我们的PriorityQueue默认为最小堆&#xff0c;堆顶总是为最小 215数组中的第K个最大元素 题目 思路解析 暴力解法&#xff08;不符合时间复杂度&#xff09; 题目要求我们找到「数组排序后的第 k 个最大的元素&#xff0c;而不是第 k 个不同的元素」。「数组排序后的第 k …