模块是一小部分代码,或者我们可以说“模块将代码库划分为小型单元,这些单元可以在应用程序中的任何地方使用。其他编程语言也有自己的模块系统,例如Java,GO和PHP;它称为软件包;在Ruby中,它是单位。
node.js当前带有2个不同的模块系统
1.commonjs(cjs) p>
2.Ecmascript模块(ESM或ES模块)
需要模块:
1.有一种将代码库分为多个文件的方法。
-
允许在不同项目中重复使用代码。
-
封装(或信息隐藏)。通常,隐藏实现复杂性并仅揭露具有明确职责的简单接口。
-
管理依赖关系。一个良好的模块系统应该使模块开发人员可以轻松地在现有模块的顶部构建,包括第三方的模块。
我们可以讨论node.js中的两种模块,但是现在,让我们看看如何使用模块系统。
模块系统有2个主要概念 -
- require是一个允许您从本地文件系统导入模块的函数
- offorts and``模块''是特殊变量,可用于从当前模块中导出公共功能
注意 - 在这一点上,我们没有比较2个模块。我们只是想了解基本的事情。
有一些流行的模式来定义模块并导出它们。通过导出一个模块,可以在整个应用程序中可用。
让我们看一下这些模式
命名出口:
最基本的概念是公开公共API使用名称导出。让我们看看以下代码。
exports.info = (message) => { console.log(
info:$ {消息} ) } exports.verbose = (message) => { console.log(
verbose:$ {messages} ) }
在这里我们可以看到,我们通过给它提供一个名称(例如信息和冗长)来导出功能。现在可用导出功能。我们可以像 -
一样使用它们const logger = require(‘./logger’) logger.info(‘This is an informational message’) logger.verbose(‘This is a verbose message’)
此方法允许我们从模块中导出所有内容。它使API公开,因此每个人都可以使用所有方法。因此,我们可以得出结论,当我们希望所有方法公开时,都应使用它。现在让我们继续下一个模式。
导出功能:
最受欢迎的模块定义模式之一包括重新分配整个模块。这种模式的主要优势在于,它允许您仅揭示单个功能,该功能为模块提供了一个明确的切入点,从而使其更容易理解和使用;它还很好地表彰了一个小表面积的原理。这种定义模块的方式在社区中也被称为替代模式。
module.exports = (message) => { console.log(
info:$ {消息} ) }
这是一种非常强大的组合,因为它仍然使模块具有单个入口点的清晰度(主要导出功能),同时它允许我们公开具有次要或更高级用例的其他功能。<<<<<<<<<<<< /p>
module.exports.verbose = (message) => { console.log(
verbose:$ {消息} ) }
此代码演示了如何使用我们刚刚定义的模块:
const logger = require('./logger') logger('This is an informational message') logger.verbose('This is a verbose message')
导出一类:
导出类的模块是导出功能的模块的专业化。导出类的模块是导出函数的模块的专业化。
class Logger {
[$ {this.name}] $ {message}
constructor (name) {
this.name = name
}
log (message) {
console.log()
info:$ {message}
}
info (message) {
this.log()
verbose:$ {message}
}
verbose (message) {
this.log()
}
}
module.exports = Logger
,我们可以使用前面的模块如下:
const Logger = require('./logger')
const dbLogger = new Logger('DB')
dbLogger.info('This is an informational message')
const accessLogger = new Logger('ACCESS')
accessLogger.verbose('This is a verbose message')
导出一类仍为模块提供一个单个入口点,但是与替代模式相比,它会揭示更多的模块内部元素。另一方面,它在扩展其功能时允许更多的功率。
导出一个实例:
我们也可以公开其实例。
class Logger {
constructor (name) {
this.count = 0
this.name = name
}
log (message) {
this.count++
console.log('[' + this.name + '] ' + message)
}
}
module.exports = new Logger('DEFAULT')
此新定义的模块然后可以如下使用:
const logger = require('./logger')
logger.log('This is an informational message')
这种模式的一个有趣的细节是,即使我们没有明确导出该类,它也不排除创建新实例的机会。实际上,我们可以依靠导出实例的构造函数构建相同类型的新实例:
const customLogger = new logger.constructor('CUSTOM')
customLogger.log('This is an informational message')
您可以看到,通过使用logger.constructor(),我们可以实例化新的logger对象。请注意,该技术必须谨慎或完全避免。考虑一下,如果模块作者决定不明确指出课程,他们可能想保留该课程。
结论:
我们涵盖了Node.js提供的所有类型的导出模式。我们可以使用的最佳选择取决于我们的要求和应用程序体系结构。
我希望您会发现这些文章有用。给它一些鼓掌,让他人也找到它!