在 node.js 中加载和执行外部 js 文件并访问局部变量?

IT技术 javascript node.js
2021-02-09 14:48:10

include('./path/to/file')在 node.js 中执行简单类型的命令是否容易/可能

我想要做的就是访问局部变量并运行脚本。人们通常如何组织比简单的 hello world 更大的 node.js 项目?(一个功能齐全的动态网站)

例如,我想要目录如下:

/models

/views

... 等等

6个回答

做一个 require('./yourfile.js');

将您希望外部访问的所有变量声明为全局变量。所以代替

var a = "hello" 这将是

GLOBAL.a="hello" 要不就

a = "hello"

这显然很糟糕。您不想污染全局范围。相反,建议方法是针对export您的函数/变量。

如果您想要 MVC 模式,请查看 Geddy。

当您说“这显然很糟糕”时,“这”指的是什么?
2021-03-22 14:48:10
@AndersonGreen:请告诉我这是一个关于范围界定的非常聪明的笑话;-)
2021-03-27 14:48:10
作为旁注……我喜欢 Express。如果您对 MVC 不那么挑剔,您也应该检查一下。
2021-03-30 14:48:10
它帮助我了解了require在你的 npm module中的外观,如果你没有在你的路径前面加上类似的前缀./
2021-04-03 14:48:10
@AndersonGreen - 他的意思是将变量放在全局范围内。
2021-04-10 14:48:10

你需要了解 CommonJS,这是一种定义module的模式。你不应该滥用 GLOBAL 范围,这总是一件坏事,相反,你可以使用 'exports' 标记,如下所示:

// circle.js

var PI = 3.14; // PI will not be accessible from outside this module

exports.area = function (r) {
  return PI * r * r;
};

exports.circumference = function (r) {
  return 2 * PI * r;
};

以及将使用我们module的客户端代码:

// client.js

var circle = require('./circle');
console.log( 'The area of a circle of radius 4 is '
           + circle.area(4));

此代码是从 node.js 文档 API 中提取的:

http://nodejs.org/docs/v0.3.2/api/modules.html

另外,如果你想使用 Rails 或 Sinatra 之类的东西,我推荐 Express(我无法发布 URL,对 Stack Overflow 感到羞耻!)

如果您正在为 Node 编写代码,那么使用 Ivan 描述的 Node module毫无疑问是要走的路。

但是,如果您需要加载已经编写vm好的JavaScript 并且不知道 node,那么module是要走的路(绝对比 更可取eval)。

例如,这是我的execfilemodule,它path在任一context或全局上下文中评估脚本

var vm = require("vm");
var fs = require("fs");
module.exports = function(path, context) {
  var data = fs.readFileSync(path);
  vm.runInNewContext(data, context, path);
}

另请注意:加载的modulerequire(…)无权访问全局上下文。

Node 支持动态需求,因此在动态加载 Node-aware module时没有理由使用这种模式。事实上,在那里使用它是有害的,因为它绕过了 Node 的require.cache,所以一个文件可能会被加载多次。
2021-03-15 14:48:10
只是require像正常:function loadService(name) { return require('./services/' + name); }然后列出但是服务是有道理的应用。
2021-03-28 14:48:10
是的,但这意味着您必须了解注册服务中的所有 1000 个module。这并不比拥有 1000 个 require 语句好。整个想法是注册服务不知道所有module,实际上它确实关心它们。module特别注册到注册服务中。那有意义吗?
2021-04-05 14:48:10
谢谢你的提示。真正的用例是当您需要临时加载module时。就像注册模式一样,您将有 1000 个module在中央服务中注册。扫描module并一个一个加载它们,而不是在您的服务中执行 1000 个 require 语句,这是一种更清晰、更好的设计......
2021-04-13 14:48:10
好的,所以要解决我提出的情况,其中您有 1000 个module,其中每个module都注册到注册表服务中,如果注册表服务中没有 1000 个 require 语句,您如何使用您提出的建议?
2021-04-14 14:48:10

如果您计划加载外部 javascript 文件的函数或对象,请使用以下代码在此上下文中加载 - 请注意 runInThisContext 方法:

var vm = require("vm");
var fs = require("fs");

var data = fs.readFileSync('./externalfile.js');
const script = new vm.Script(data);
script.runInThisContext();

// here you can use externalfile's functions or objects as if they were instantiated here. They have been added to this context. 
经过大量的搜索和摸索,这种技术对我有用。我的文件是为浏览器编写的,可以直接使用并声明一个变量,例如:const aVar = { thing: 'a' }
2021-03-26 14:48:10

扩展@Shripad@Ivan的答案,我建议您使用 Node.js 的标准module.export功能。

在你的常量文件(例如 constants.js)中,你会写这样的常量:

const CONST1 = 1;
module.exports.CONST1 = CONST1;

const CONST2 = 2;
module.exports.CONST2 = CONST2;

然后在要使用这些常量的文件中,编写以下代码:

const {CONST1 , CONST2} = require('./constants.js');

如果您以前从未见过const { ... }语法:那就是解构赋值