JavaScript 导入模块混淆

Posted

技术标签:

【中文标题】JavaScript 导入模块混淆【英文标题】:JavaScript importing module confusion 【发布时间】:2022-01-24 03:49:13 【问题描述】:

当我导入“http”模块时,我使用

Var http = require('http');
http.createServer(function(req,res)......
.listen(8080)

但是当我导入 express 模块时,我使用

const express = require('express');
const app = express();
app.get('/', (req,res)=>........

app.listen()

为什么我需要在代码中创建const app = express();而不是const app = http();

【问题讨论】:

因为 express 有构造函数而 http 没有。与导入无关 【参考方案1】:

express 从模块中导出一个函数。 http 导出具有函数的对象。

每个库作者都选择自己的方式来导出他们的库。

这是一个如何实现它们的示例。

module.exports = function() 
 // code here
 return 
   // calling the function returns an object
 

module.exports = 
  createServer() 
  

【讨论】:

【参考方案2】:

您的任何问题都与导入无关。

当你这样做时:

const app = express();

您正在创建 Express 类的实例。 express 函数是一个工厂函数,当您调用它时会创建一个对象(在这种情况下,它是一个函数对象)。它不是 http 服务器。它既是一堆方法的父对象,又是路由传入 http 请求的主要请求处理程序。

当你这样做时:

app.listen()

这将创建您的 http 服务器。实际上,.listen() 方法中的代码只是为您创建了 http 服务器并将 app 注册为传入连接的请求处理程序。

如果您查看code 对应的app.listen(),您只会看到:

app.listen = function listen() 
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
;

它只是创建一个以app 函数/对象作为主要请求处理程序的http 服务器实例,然后它调用.listen() 来启动服务器。

所以,app.listen() 只是一个捷径。您可以自己使用http 模块来创建自己的服务器对象,然后使用它注册您的app 对象,但app.listen() 只是为您做这些。


作为教学替代方案,还有许多其他方法可以安排代码。你也可以这样做:

const express = require('express');       // load express module
const app = express();                    // create express instance
const http = require('http');             // load http module
const server = http.createServer(app);    // create http server
                                          // and register express listener
server.listen(80);                        // start http server

这不会利用app.listen() 中的快捷方式,但效果相同。

【讨论】:

谢谢,如果 express 是一个类,那么为什么 const app = express(); 中没有“new”比如 const app = new express(); @Aakash - 正如我所说,express() 函数是一个工厂函数。它创建对象本身的一个实例。它在该函数中执行new。它不直接公开类构造函数。相反,您调用工厂函数来获取该类的新实例。这是创建某个类的新实例的一种设计模式。它可能是这样实现的,因为 Express 在 javascript 具有 class 语法之前就已经存在,但偶尔更喜欢工厂函数还有其他原因。

以上是关于JavaScript 导入模块混淆的主要内容,如果未能解决你的问题,请参考以下文章

javascript导入自定义模块

尝试导入没有模块/包的 javascript 库

将 Vue npm 模块导入我的 javascript 文件

在 JavaScript 模块中正确导入 Firebase 存储

如何从 javascript/typescript 模块文件(导入/导出)访问 Vuex 商店?

javascript 模块导入导出