简体   繁体   English

在 node.js 中使用外部 javascript 文件而不使用 export 和 require

[英]Using external javascript files in node.js without using export and require

I don't like the whole export/require stuff in node, it takes too long.我不喜欢节点中的整个导出/需要的东西,它需要太长时间。 Let's say I have a file server.js and I want to use functions in whatever.js.假设我有一个文件 server.js,我想在 whatever.js 中使用函数。 in html I just add this to the header:在 html 中,我将其添加到 header 中:

<script src='whatever.js'></script>

and then I can just use all the functions of whatever.js in my body's script.然后我就可以在我身体的脚本中使用 whatever.js 的所有功能。

But in node, in the server.js file I'd do:但是在节点中,在 server.js 文件中我会这样做:

var myobject = require('./whatever.js');

but then I need to set it to myobject, and further I need to go to whatever.js and manually decide what functions I want to export.但是我需要将它设置为 myobject,而且我需要将 go 设置为 whatever.js 并手动决定我想要导出的功能。 not to mention that typing myobject.someFunction() is alot longer to write than someFunction() and I need to remember what I exposed/didn't expose.更不用说输入 myobject.someFunction() 比 someFunction() 写起来要长得多,我需要记住我暴露/没有暴露的内容。

I wanted something where I could just go:我想要一些我只能 go 的东西:

require('./whatever.js');

and it puts it ALL in global, no bs.并将其全部放在全球范围内,没有bs。 like in good old html/javascript.就像在好的旧 html/javascript 中一样。 Is there a way to do this in node?有没有办法在节点中执行此操作?

This will do the trick, 这样就可以了,

var fs = require('fs');

eval(fs.readFileSync('whatever.js')+'');
 // here call functions from whatever.js file

(I realize this is an old thread but wanted to leave a note here for posterity.) (我意识到这是一个旧线程,但想在这里为后代留下一张纸条。)

Here in 2022 there are several approaches for executing code from different files with Node.js:在 2022 年,有几种方法可以使用 Node.js 从不同文件执行代码:

ESM: Use standard ECMAScript modules ESM:使用标准的 ECMAScript 模块

At the time of this writing, much of the node ecosystem (ie packages on npm) is in the process of transitioning to this paradigm, and there are some associated growing pains (eg things like __dirname are only available in CJS not ESM, though the workaround is easy ).在撰写本文时,许多节点生态系统(即 npm 上的包)正在过渡到这种范式,并且存在一些相关的成长烦恼(例如__dirname类的东西仅在 CJS 而不是 ESM 中可用,尽管解决方法很简单)。 For most developers, it would be advisable to become comfortable with this standard as it transcends node.js (ie is implemented in other runtimes like Deno and web browsers) and has been years in the making.对于大多数开发人员来说,最好适应这个标准,因为它超越了 node.js(即在Deno和 web 浏览器等其他运行时中实现)并且已经制定多年。

CJS: Use the original "CommonJS" module mechanism, eg require('./some-script.js') CJS:使用原始的“CommonJS”模块机制,eg require('./some-script.js')

It should be noted, particularly for the OP, that even though the "intended" way to use CJS modules is to export functions, constants, etc. and import them explicitly, it is possible to define everything in global scope using globalThis , though I would not recommend this.应该注意,特别是对于 OP,即使使用 CJS 模块的“预期”方式是导出函数、常量等并显式导入它们,也可以使用globalThis定义全局 scope 中的所有内容,尽管我不会推荐这个。

// my-script.js
require('./foo.js');
require('./bar.js');
foo(); // This is foo from <...>foo.js
console.log(`bar = ${bar} (in ${__filename})`); // bar = 123 (in <...>my-script.js)

// foo.js
globalThis.foo = function() {
  console.log(`This is foo from ${__filename}`);
}

// bar.js
globalThis.bar = 123;

If you try omitting globalThis.如果您尝试省略globalThis. you'll find that foo and bar are no longer defined in the main script because require "wraps them" in "module scope."您会发现主脚本中不再定义foobar ,因为require在“模块 scope”中“包装了它们”。

Use eval使用eval

In my experience, there are very few legitimate use cases for eval (see Never use eval()! ).根据我的经验, eval的合法用例很少(请参阅切勿使用 eval()! )。 Nevertheless, the functionality requested in this question is precisely what eval provides: "run some code as if it were written right here" and you can feed it from a file, as explained above by Mehul Prajapati然而,这个问题中要求的功能正是eval提供的:“运行一些代码,就好像它是在这里写的一样”,你可以从文件中提供它,正如上面 Mehul Prajapati所解释的

// include.js 
// Defines a global function that works like C's "#include" preprocessor directive
const { readFileSync } = require('fs');
globalThis.include = function(scriptFile) {
  console.warn('!!! EXTREMELY INSECURE !!!');
  eval(readFileSync(scriptFile, 'utf-8'));
};


// main.js
require('./include.js'); // loads global include

// (I sure hope you completely trust these sources)
include('./foo.js');
include('./bar.js');

Note: Something that has contributed to much of my confusion in the past is that there have been competing standards/conventions/APIs that use some of the same identifiers, namely require , which require.js and other bundlers that support AMD (Asynchronous Module Definition) use with different semantics.注意:过去造成我很多困惑的是,存在使用一些相同标识符的竞争标准/约定/API,即require ,它require.js其他支持AMD 的捆绑(异步模块定义)使用不同的语义。 So for someone building a web application (using AMD for modules in web browsers) with node.js tooling (using CJS for modules locally) it can be frustrating to keep the functions straight, especially if it's an Electron application, which can expose Node.js APIs to scripts running in the renderer (browser).因此,对于使用 node.js 工具(在本地使用 CJS 模块)构建 web 应用程序(在 web 浏览器中使用 AMD 模块)的人来说,保持功能直接可能会令人沮丧,特别是如果它是一个Electron应用程序,它可以将 Node.js API 暴露给脚本在渲染器(浏览器)中运行。 If you find yourself confused why a module is "not found" in a situation like that, check the stack trace to see which require is being called (and you may have to wrap/rename them on globalThis or something to avoid collisions).如果您发现自己对为什么在这种情况下“找不到”模块感到困惑,请检查堆栈跟踪以查看正在调用哪个require (并且您可能必须在globalThis或其他东西上包装/重命名它们以避免冲突)。

Further reading:延伸阅读:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM