前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >module.exports和exports,应该用哪个

module.exports和exports,应该用哪个

作者头像
chuckQu
发布于 2023-09-12 00:24:20
发布于 2023-09-12 00:24:20
24000
代码可运行
举报
文章被收录于专栏:前端F2E前端F2E
运行总次数:0
代码可运行

在 Node.js 编程中,模块是独立的功能单元,可以在项目间共享和重用。作为开发人员,模块让我们的生活更轻松,因为我们可以使用模块来增强应用程序的功能,而无需亲自编写。它们还允许我们组织和解耦代码,从而使应用程序更易于理解、调试和维护。

在这篇文章中,我将介绍如何在 Node.js 中使用模块,重点是如何导出和消费它们。

各种模块格式

由于 JavaScript 最初没有模块的概念,因此随着时间的推移,出现了各种相互竞争的格式。下面列出了需要注意的主要格式:

  • Asynchronous Module Definition (AMD)[1]格式用于浏览器,使用define函数来定义模块。
  • CommonJS (CJS)[2]格式用于Node.js,使用requiremodule.exports来定义依赖和模块。npm 生态系统就是基于这种格式构建的。
  • ES Module (ESM)格式。从 ES6(ES2015)开始,JavaScript 支持原生模块格式。它使用 export 关键字导出模块的公共 API,使用 import 关键字导入模块。
  • System.register[3]格式用于支持 ES5 中的 ES6 模块。
  • Universal Module Definition (UMD)[4]格式可以用于浏览器和Node.js。当一个模块需要被多个不同的模块加载器导入时,它就会非常有用。

请注意,本文仅涉及 Node.js 的标准 CommonJS格式。

引入模块

Node.js带来了一系列内置模块,这样我们就可以直接在代码中使用而不需要安装它们。要使用它们,我们需要使用require关键字引入模块,并赋值给变量。然后就可以用它来调用模块公开的任何方法。

举个例子,要罗列出目录下的内容,可以使用文件系统模块,以及该模块的readdir方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const fs = require('fs');
const folderPath = '/home/jim/Desktop/';

fs.readdir(folderPath, (err, files) => {
  files.forEach(file => {
    console.log(file);
  });
});

请注意,在 CommonJS 中,模块是同步加载的,并按照模块出现的顺序进行处理。

创建并导出模块

现在,让我们看看如何创建自己的模块并导出它。创建user.js文件并添加下列代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const getName = () => {
  return 'Jim';
};

exports.getName = getName;

然后在同一文件夹下创建index.js,并添加下列代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const user = require('./user');
console.log(`User: ${user.getName()}`);

使用node index.js运行代码,你会在终端上看到下列输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
User: Jim

发生了啥?好吧,如果你查看user.js文件,你会注意到我们定义了一个getName函数,然后使用exports关键字让它在任意导入的地方可用。在index.js中,我们导入了该函数并执行了它。还需要注意require语句,该模型名称有着./前缀,意味着它是本地文件。还要注意的是,此处不需要添加文件扩展名。

导出多个方法和值

我们可以用同样的方式导出多个方法和值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const getName = () => {
  return 'Jim';
};

const getLocation = () => {
  return 'Munich';
};

const dateOfBirth = '12.01.1982';

exports.getName = getName;
exports.getLocation = getLocation;
exports.dob = dateOfBirth;

index.js中这么使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const user = require('./user');
console.log(
  `${user.getName()} lives in ${user.getLocation()} and was born on ${user.dob}.`
);

上述代码的产出是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Jim lives in Munich and was born on 12.01.1982.

注意我们给导出的 dateOfBirth 变量起的名字可以是任何我们喜欢的名字(本例中为 dob)。它不必与原始变量名相同。

语法的变化

我还应该提到,可以在导出过程中导出方法和值,而不仅仅是在文件末尾导出。

举个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
exports.getName = () => {
  return 'Jim';
};

exports.getLocation = () => {
  return 'Munich';
};

exports.dob = '12.01.1982';

多亏了解构赋值,我们可以挑选想要导入的方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const { getName, dob } = require('./user');
console.log(
  `${getName()} was born on ${dob}.`
);

导出默认值

上面的示例中,我们单独导出了函数和值。这对于整个应用程序都可能需要的辅助函数来说非常方便,但当你有一个只导出一样东西的模块时,使用 module.exports 会更常见:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class User {
  constructor(name, age, email) {
    this.name = name;
    this.age = age;
    this.email = email;
  }

  getUserStats() {
    return `
      Name: ${this.name}
      Age: ${this.age}
      Email: ${this.email}
    `;
  }
}

module.exports = User;

index.js中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const User = require('./user');
const jim = new User('Jim', 37, 'jim@example.com');

console.log(jim.getUserStats());

代码输出如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Name: Jim
Age: 37
Email: jim@example.com

module.exports和exports的区别

在开源世界里,你可以会遇到下列语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module.exports = {
  getName: () => {
    return 'Jim';
  },

  getLocation: () => {
    return 'Munich';
  },

  dob: '12.01.1982',
};

在这里,我们将想要导出的函数和值分配给 module 上的 exports 属性,当然,这样做效果很好:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const { getName, dob } = require('./user');
console.log(
  `${getName()} was born on ${dob}.`
);

那么,module.exportsexports的不同之处是什么?一个只是另一个的别名吗?

有点,但不完全是……

为了阐明我的意思,我们更改index.js中的代码,打印module的值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
console.log(module);

输出如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Module {
  id: '.',
  exports: {},
  parent: null,
  filename: '/home/jim/Desktop/index.js',
  loaded: false,
  children: [],
  paths:
   [ '/home/jim/Desktop/node_modules',
     '/home/jim/node_modules',
     '/home/node_modules',
     '/node_modules' ] }

正如你看到的,module有一个exports属性。在exports上添加一些东西:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// index.js
exports.foo = 'foo';
console.log(module);

输出如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Module {
  id: '.',
  exports: { foo: 'foo' },
  ...

exports 分配的属性也会将它们添加到 module.exports。这是因为(至少最初)exports 是对 module.exports 的引用。

应该用哪个

由于 module.exportsexports 都指向同一个对象,因此使用哪个通常并不重要。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
exports.foo = 'foo';
module.exports.bar = 'bar';

这段代码将导致模块的导出对象为 { foo: 'foo', bar: 'bar' }

不过,有一个注意事项。无论你将什么赋值给 module.exports ,都将从你的模块中导出什么。

那么,请看下面的内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
exports.foo = 'foo';
module.exports = () => { console.log('bar'); };

这样只会导出一个匿名函数。foo 变量将被忽略。

总结

模块已成为 JavaScript 生态系统不可或缺的一部分,它使我们能够将较小的部分组成大型程序。我希望本文能为你介绍如何在 Node.js 中使用模块,并帮助你揭开模块语法的神秘面纱。

  • 本文译自:https://www.sitepoint.com/understanding-module-exports-exports-node-js/

参考资料

[1]

Asynchronous Module Definition (AMD): https://en.wikipedia.org/wiki/Asynchronous_module_definition

[2]

CommonJS (CJS): https://en.wikipedia.org/wiki/CommonJS

[3]

System.register: https://github.com/systemjs/systemjs/blob/master/docs/system-register.md

[4]

Universal Module Definition (UMD): https://riptutorial.com/javascript/example/16339/universal-module-definition--umd-

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-24 22:34,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端F2E 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
150B token从头训练,普林斯顿Meta发布完全可微MoE架构Lory
不同于大多数模型使用字母缩略起名,论文作者在脚注中解释道,Lory是一种羽毛有彩虹颜色的鹦鹉,和「软MoE」的精神非常相似。
新智元
2024/05/22
1300
150B token从头训练,普林斯顿Meta发布完全可微MoE架构Lory
无需额外训练,基于 Llama-2模型,通过 Model-GLUE 实现大规模语言模型的聚合与集成 !
大型语言模型(LLMs)在各种自然语言任务上展示了无与伦比的性能,涵盖了常识推理、问答以及甚至像数学和编程等专业化领域。LLM的有效性基于扩展定律,该定律提出,模型和训练数据规模的增加与模型性能的提升相关[27]。然而,随着LLM继续扩展,计算开销和数据需求也在增加。
AIGC 先锋科技
2024/11/08
1530
无需额外训练,基于 Llama-2模型,通过 Model-GLUE 实现大规模语言模型的聚合与集成  !
稀疏性在机器学习中的发展趋势:MoE、稀疏注意力机制
每天给你送来NLP技术干货! ---- 作者:唐工 来源:https://zhuanlan.zhihu.com/p/463352552 编辑:李rumor Sparsity, ..., is another important algorithmic advance that can greatly improve efficiency. 稀疏性,是(神经架构搜索)之外另一个重要的算法进步,可以大大提高效率。The use of sparsity in models is ... very high po
zenRRan
2022/03/15
6.3K0
阿里云通义大模型新技术:MoE模型训练专家平衡的关键细节
本周,在阿里云通义千问 Qwen 团队提交的一篇论文中,研究人员发现了目前最热门的 MoE(混合专家模型)训练中存在的一个普遍关键问题,并提出一种全新的方法——通过轻量的通信将局部均衡放松为全局均衡,使得 MoE 模型的性能和专家特异性都得到了显著的提升。
机器之心
2025/02/03
1240
阿里云通义大模型新技术:MoE模型训练专家平衡的关键细节
一文深入了解DeepSeek-R1:模型架构
DeepSeek-R1 从其基础模型 DeepSeek-V3-Base 继承了 128K 上下文长度。最初,DeepSeek-V3 使用 4K 上下文长度进行预训练。然后,利用 YaRN 技术,两阶段上下文长度扩展首先将其增加到 32K,然后增加到 128K。
致Great
2025/02/14
1.6K0
一文深入了解DeepSeek-R1:模型架构
深度求索开源国内首个 MoE 大模型 | DeepSeekMoE:在专家混合语言模型中实现终极专家专业化
在大语言模型时代,混合专家模型(MoE)是一种很有前途的架构,用于在扩展模型参数时管理计算成本。然而,传统的 MoE 架构(如 GShard)会激活 N 位专家中的 top-K 专家,但在确保专家专业化(即每位专家获取的知识不重叠且重点突出)方面面临挑战。作为回应,研究者提出了 DeepSeekMoE 架构,以实现终极的专家专业化。它涉及两个主要战略:
叶庭云
2024/05/25
1.9K0
深度求索开源国内首个 MoE 大模型 | DeepSeekMoE:在专家混合语言模型中实现终极专家专业化
微软让MoE长出多个头,大幅提升专家激活率
混合专家(MoE)是个好方法,支持着现在一些非常优秀的大模型,比如谷歌家的 Gemini 1.5 以及备受关注的 Mixtral 8x7B。
机器之心
2024/05/14
1210
微软让MoE长出多个头,大幅提升专家激活率
训不动Mixtral,要不试试LLaMA-MoE?
随着各种各样增强版LLaMA的出现,Mixture-of-Expert(MoE)类模型越来越受大家关注。而LLaMA-MoE正是基于LLaMA系列和SlimPajama的MoE模型。它显著的一个好处是减小了模型大小,降低了训练代价。通过以下两个步骤进行构建:
zenRRan
2023/12/28
5380
训不动Mixtral,要不试试LLaMA-MoE?
3万字详细解析清华大学最新综述工作:大模型高效推理综述
大模型由于其在各种任务中的出色表现而引起了广泛的关注。然而,大模型推理的大量计算和内存需求对其在资源受限场景的部署提出了挑战。业内一直在努力开发旨在提高大模型推理效率的技术。本文对现有的关于高效大模型推理的文献进行了全面的综述总结。首先分析了大模型推理效率低下的主要原因,即大模型参数规模、注意力计算操的二次复杂度作和自回归解码方法。然后,引入了一个全面的分类法,将现有优化工作划分为数据级别、模型级别和系统级别的优化。此外,本文还对关键子领域的代表性方法进行了对比实验,以及分析并给出一定的见解。最后,对相关工作进行总结,并对未来的研究方向进行了讨论。
zenRRan
2024/06/07
2.2K0
3万字详细解析清华大学最新综述工作:大模型高效推理综述
大模型系列之解读MoE
Mixtral 8x7B 的推出, 使我们开始更多地关注 基于MoE 的大模型架构, 那么,什么是MoE呢?
半吊子全栈工匠
2024/05/07
1.6K0
大模型系列之解读MoE
深度揭秘爆火MoE!GPT-4关键架构,成开源模型逆袭杀手锏
Mistral上周末丢出的磁力链接震惊了开源圈子,这个7B×8E的开源MoE大模型性能已经到达了LLaMA2 70B的级别!
新智元
2023/12/12
8470
深度揭秘爆火MoE!GPT-4关键架构,成开源模型逆袭杀手锏
国产五大模型之一MiniMax 使用国内首个MOE架构
阿里被曝2024年面向AIGC的第二次大手笔投资来了——加注大模型赛道独角兽Minimax,领投至少6亿美元。
存内计算开发者
2024/05/21
2K0
哈工大/齐鲁工大/北京师范联合提出 PMoL:结合 LoRA 与 MoE 框架,实现高效偏好混合与降低训练成本的新方法 !
目前,基于人类偏好的风格和道德价值观的预训练语言模型(RLHF,Christiano等人,2017;Ouyang等人,2022)是一种广泛使用的方法,用于将预训练语言模型与人类偏好对齐。这种方法需要使用人类标注的偏好数据来构建奖励模型,然后使用强化学习来训练预训练语言模型。
AIGC 先锋科技
2024/12/19
1990
哈工大/齐鲁工大/北京师范联合提出 PMoL:结合 LoRA 与 MoE 框架,实现高效偏好混合与降低训练成本的新方法 !
大模型微调新范式:当LoRA遇见MoE
左侧:原始版本的LoRA,权重是稠密的,每个样本都会激活所有参数;右侧:与混合专家(MoE)框架结合的LoRA,每一层插入多个并行的LoRA权重(即MoE中的多个专家模型),路由模块(Router)输出每个专家的激活概率,以决定激活哪些LoRA模块。
zenRRan
2024/03/02
2.8K0
大模型微调新范式:当LoRA遇见MoE
如何高效训练 Transformer?微软亚研院开源TorchScale工具包
近期,微软亚洲研究院从深度学习基础理论出发,研发并推出了 TorchScale 开源工具包。TorchScale 工具包通过采用 DeepNet、Magneto 和 X-MoE 等最先进的建模技术,可以帮助研究和开发人员提高建模的通用性和整体性能,确保训练模型的稳定性及效率,并允许以不同的模型大小扩展 Transformer 网络。 如今,在包括语音、自然语言处理(NLP)、计算机视觉(CV)、多模态模型和 AI for Science 等领域的研究中,Transformer 已经成为一种通用网络结构,加速
AI科技大本营
2023/02/23
5320
如何高效训练 Transformer?微软亚研院开源TorchScale工具包
Mixture-of-Experts (MoE) 经典论文一览
最近接触到 Mixture-of-Experts (MoE) 这个概念,才发现这是一个已经有30多年历史、至今依然在被广泛应用的技术,所以读了相关的几篇经典论文,在这里总结一下。
beyondGuo
2022/12/01
2.3K0
Mixture-of-Experts (MoE) 经典论文一览
纯MLP在下游任务上欠佳?Meta AI等提出稀疏MLP,超越transformer
机器之心报道 机器之心编辑部 来自 Meta AI 和纽约州立大学布法罗分校的研究者分析了 MLP 在表达能力方面的局限性,并提出了在特征和输入(token)维度上带有混合专家系统(MoE)的稀疏激活 MLP。 作为基于注意力模型的替代方案,纯 MLP 架构吸引了越来越多的关注。在 NLP 中,gMLP 等近期工作表明,纯 MLP 在语言建模方面可以达到与 transformer 相当的性能,但在下游任务中弱于 transformer。 来自 Meta AI 和纽约州立大学布法罗分校的研究者分析了 MLP
机器之心
2022/04/18
5620
纯MLP在下游任务上欠佳?Meta AI等提出稀疏MLP,超越transformer
MoE训练论文解读之Megablocks:打破动态路由限制
GPT-4用了Mixture-of-Experts(MoE)架构,引起了广泛关注。然而,MoE训练并不是一项简单的任务,它面临着一些主要的挑战和难点:
NewBeeNLP
2023/11/08
2.1K0
MoE训练论文解读之Megablocks:打破动态路由限制
DeepSeek和月之暗面的论文撞车了!!
昨天下午,DeepSeek 发布了一篇新论文,提出了一种改进版的注意力机制 NSA;加上还有创始人兼 CEO 梁文锋亲自参与,一时之间吸引眼球无数,参阅报道《 刚刚!DeepSeek团队丢出注意力新机制重磅论文》。
小白学视觉
2025/02/20
1330
DeepSeek和月之暗面的论文撞车了!!
Y-MoD:探索深度混合适应性,适用于多模式大语言模型 !
近年来,自然语言处理(NLP)领域大型语言模型(LLMs)取得了巨大成功,这吸引了越来越多的关注,以将其扩展到视觉语言(VL)任务。尽管取得了进步,但最近的多模态大型语言模型(MLLMs)往往受到其昂贵的计算成本的批评。例如,现有 MLLMs 的推理速度仍远低于实际需求,例如每秒4.7个样本。受NLP进步的推动,最近的技术进步采用了混合专家(MoEs)来减少MLLMs的“激活参数”,从而在效率和性能之间实现了权衡。
AIGC 先锋科技
2024/11/06
1540
Y-MoD:探索深度混合适应性,适用于多模式大语言模型 !
推荐阅读
相关推荐
150B token从头训练,普林斯顿Meta发布完全可微MoE架构Lory
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验