在Node.js中,如何从我的其他文件“包含”function?

比方说,我有一个名为app.js的文件。 很简单:

var express = require('express'); var app = express.createServer(); app.set('views', __dirname + '/views'); app.set('view engine', 'ejs'); app.get('/', function(req, res){ res.render('index', {locals: { title: 'NowJS + Express Example' }}); }); app.listen(8080); 

如果我在“tools.js”中有一个函数呢? 我如何将它们导入到apps.js中使用?

或者…我应该把“工具”变成一个模块,然后需要它吗? <<看起来很难,我宁愿做tools.js文件的基本导入。

你可以要求任何js文件,你只需要声明你想要公开的内容。

 // tools.js // ======== module.exports = { foo: function () { // whatever }, bar: function () { // whatever } }; var zemba = function () { } 

并在您的应用程序文件中:

 // app.js // ====== var tools = require('./tools'); console.log(typeof tools.foo); // => 'function' console.log(typeof tools.bar); // => 'function' console.log(typeof tools.zemba); // => undefined 

如果,尽pipe所有其他答案,你仍然希望传统上包含一个文件在node.js源文件,你可以使用这个:

 var fs = require('fs'); // file is included here: eval(fs.readFileSync('tools.js')+''); 
  • 空string连接“ +''是获取文件内容所需的string而不是对象(如果您愿意,也可以使用.toString() )。
  • eval()不能在函数内部使用, 必须在全局范围内调用,否则将不能访问函数或variables(即不能创buildinclude()实用程序函数或类似的东西)。

请注意,在大多数情况下这是不好的做法 ,你应该写一个模块 。 但是,在极less数情况下,您的本地环境/名称空间的污染是您真正想要的。

更新2015-08-06

还请注意,这不会与"use strict"; (当处于“严格模式”时 ),因为在导入的文件中定义的函数和variables不能被导入的代码访问 。 严格模式强制执行由新版本的语言标准定义的一些规则。 这可能是避免此处所述解决scheme的另一个原因。

你不需要新的function,也不需要新的模块。 如果你不想使用命名空间,你只需要执行你所调用的模块。

在tools.js中

 module.exports = function() { this.sum = function(a,b) { return a+b }; this.multiply = function(a,b) { return a*b }; //etc } 

在app.js中

或者像myController.js的其他.js文件:

代替

var tools = require('tools.js')这迫使我们使用命名空间并调用tools.sum(1,2);

我们可以直接打电话

 require('tools.js')(); 

接着

 sum(1,2); 

在我的情况下,我有一个控制器ctrls.js的文件

 module.exports = function() { this.Categories = require('categories.js'); } 

require('ctrls.js')()之后,我可以在每个上下文中使用Categories作为公共类。

这是一个简单而简单的解释:

Server.js内容:

 // Include the public functions from 'helpers.js' var helpers = require('./helpers'); // Let's assume this is the data which comes from the database or somewhere else var databaseName = 'Walter'; var databaseSurname = 'Heisenberg'; // Use the function from 'helpers.js' in the main file, which is server.js var fullname = helpers.concatenateNames(databaseName, databaseSurname); 

Helpers.js内容:

 // 'module.exports' is a node.JS specific feature, it does not work with regular JavaScript module.exports = { // This is the function which will be called in the main file, which is server.js // The parameters 'name' and 'surname' will be provided inside the function // when the function is called in the main file. // Example: concatenameNames('John,'Doe'); concatenateNames: function (name, surname) { var wholeName = name + " " + surname; return wholeName; }, sampleFunctionTwo: function () { } }; // Private variables and functions which will not be accessible outside this file var privateFunction = function () { }; 

我也在寻找一个NodeJS的'include'函数,我检查了Udo G提出的解决scheme – 请参阅https://stackoverflow.com/a/8744519/2979590消息。; 他的代码不适用于我包含的JS文件。 最后我解决了这个问题:

 var fs = require("fs"); function read(f) { return fs.readFileSync(f).toString(); } function include(f) { eval.apply(global, [read(f)]); } include('somefile_with_some_declarations.js'); 

当然,这有帮助。

说我们想调用函数ping()添加(30,20)main.js lib.js文件

main.js

 lib = require("./lib.js") output = lib.ping(); console.log(output); //Passing Parameters console.log("Sum of A and B = " + lib.add(20,30)) 

lib.js

 this.ping=function () { return "Ping Success" } 
 //Functions with parameters this.add=function(a,b) { return a+b } 

Node.js中的vm模块提供了在当前上下文(包括全局对象)内执行JavaScript代码的能力。 请参阅http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

请注意,截至今天,vm模块中存在一个错误,它会阻止runInThisContext从新的上下文中调用时执行正确的操作。 这只在你的主程序在新的上下文中执行代码,然后代码调用runInThisContext时才起作用。 见https://github.com/joyent/node/issues/898

不幸的是,Fernando提出的with(全局)方法不适用于“function foo(){}”这样的命名函数

简而言之,下面是一个适用于我的include()函数:

 function include(path) { var code = fs.readFileSync(path, 'utf-8'); vm.runInThisContext(code, path); } 

创build两个js文件

 // File cal.js module.exports = { sum: function(a,b) { return a+b }, multiply: function(a,b) { return a*b } }; 

主要的js文件

 // File app.js var tools = require("./cal.js"); var value = tools.sum(10,20); console.log("Value: "+value); 

产量

 value: 30 

Udo G.说:

  • eval()不能在函数内部使用,必须在全局范围内调用,否则将不能访问函数或variables(即不能创buildinclude()实用程序函数或类似的东西)。

他是对的,但是有一种方法可以从function上影响全球范围。 改进他的例子:

 function include(file_) { with (global) { eval(fs.readFileSync(file_) + ''); }; }; include('somefile_with_some_declarations.js'); // the declarations are now accessible here. 

希望,这有帮助。

你可以把你的函数放在全局variables中,但是最好把你的工具脚本变成一个模块。 这真的不是太难 – 只需将公共API添加到exports对象。 了解一些更多细节了解Node.js的exports模块 。

在我看来,另一种方法是在你使用(function(/ * things something * /){})()调用require()函数时,执行lib文件中的所有内容 这样做将使所有这些函数成为全局范围,就像eval()解决scheme一样

SRC / lib.js

 (function () { funcOne = function() { console.log('mlt funcOne here'); } funcThree = function(firstName) { console.log(firstName, 'calls funcThree here'); } name = "Mulatinho"; myobject = { title: 'Node.JS is cool', funcFour: function() { return console.log('internal funcFour() called here'); } } })(); 

然后在你的主代码中,你可以按照下面的名字来调用你的函数:

main.js

 require('./src/lib') funcOne(); funcThree('Alex'); console.log(name); console.log(myobject); console.log(myobject.funcFour()); 

将做出这个输出

 bash-3.2$ node -v v7.2.1 bash-3.2$ node main.js mlt funcOne here Alex calls funcThree here Mulatinho { title: 'Node.JS is cool', funcFour: [Function: funcFour] } internal funcFour() called here undefined 

当你调用我的object.funcFour()时注意 undefined ,如果你用eval()加载,它将是一样的。 希望它有助于:)

它和我一样,像下面一样….

Lib1.js

 //Any other private code here // Code you want to export exports.function1 = function1 (params) {.......}; exports.function2 = function2 (params) {.......}; // Again any private code 

现在在Main.js文件中需要包含Lib1.js

 var mylib = requires('lib1.js'); mylib.function1(params); mylib.function2(params); 

请记住将Lib1.js放在node_modules文件夹中

包含文件并在给定的(非全局)上下文中运行

fileToInclude.js

 define({ "data": "XYZ" }); 

main.js

 var fs = require("fs"); var vm = require("vm"); function include(path, context) { var code = fs.readFileSync(path, 'utf-8'); vm.runInContext(code, vm.createContext(context)); } // Include file var customContext = { "define": function (data) { console.log(data); } }; include('./fileToInclude.js', customContext); 

这是迄今为止我创造的最好的方式。

 var fs = require('fs'), includedFiles_ = {}; global.include = function (fileName) { var sys = require('sys'); sys.puts('Loading file: ' + fileName); var ev = require(fileName); for (var prop in ev) { global[prop] = ev[prop]; } includedFiles_[fileName] = true; }; global.includeOnce = function (fileName) { if (!includedFiles_[fileName]) { include(fileName); } }; global.includeFolderOnce = function (folder) { var file, fileName, sys = require('sys'), files = fs.readdirSync(folder); var getFileName = function(str) { var splited = str.split('.'); splited.pop(); return splited.join('.'); }, getExtension = function(str) { var splited = str.split('.'); return splited[splited.length - 1]; }; for (var i = 0; i < files.length; i++) { file = files[i]; if (getExtension(file) === 'js') { fileName = getFileName(file); try { includeOnce(folder + '/' + file); } catch (err) { // if (ext.vars) { // console.log(ext.vars.dump(err)); // } else { sys.puts(err); // } } } } }; includeFolderOnce('./extensions'); includeOnce('./bin/Lara.js'); var lara = new Lara(); 

你仍然需要通知你想要输出

 includeOnce('./bin/WebServer.js'); function Lara() { this.webServer = new WebServer(); this.webServer.start(); } Lara.prototype.webServer = null; module.exports.Lara = Lara; 

就像你有一个文件abc.txt等等?

创build2个文件: fileread.jsfetchingfile.js ,然后在fileread.js写下这段代码:

 function fileread(filename) { var contents= fs.readFileSync(filename); return contents; } var fs = require("fs"); // file system //var data = fileread("abc.txt"); module.exports.fileread = fileread; //data.say(); //console.log(data.toString()); } 

fetchingfile.js写下这段代码:

 function myerror(){ console.log("Hey need some help"); console.log("type file=abc.txt"); } var ags = require("minimist")(process.argv.slice(2), { string: "file" }); if(ags.help || !ags.file) { myerror(); process.exit(1); } var hello = require("./fileread.js"); var data = hello.fileread(ags.file); // importing module here console.log(data.toString()); 

现在,在terminal中:$ node fetchingfile.js –file = abc.txt

您传递文件名作为参数,而且包含readfile.js所有文件而不是传递它。

谢谢

你可以简单的只require('./filename')

例如。

 // file: index.js var express = require('express'); var app = express(); var child = require('./child'); app.use('/child', child); app.get('/', function (req, res) { res.send('parent'); }); app.listen(process.env.PORT, function () { console.log('Example app listening on port '+process.env.PORT+'!'); }); 
 // file: child.js var express = require('express'), child = express.Router(); console.log('child'); child.get('/child', function(req, res){ res.send('Child2'); }); child.get('/', function(req, res){ res.send('Child'); }); module.exports = child; 

请注意:

  1. 你不能在子文件上监听PORT,只有父Express模块​​有PORT监听器
  2. 孩子正在使用“路由器”,而不是家长快递模式。

我也在寻找一个包含代码而不写模块的选项, 使用来自不同项目的相同testing独立的来源为Node.js服务 – 和jmparatte的答案为我做了。

好处是,你不污染名字空间,我没有用"use strict";麻烦"use strict"; 它运作良好。

这里是一个完整的示例

加载脚本 – /lib/foo.js

 "use strict"; (function(){ var Foo = function(e){ this.foo = e; } Foo.prototype.x = 1; return Foo; }()) 

SampleModule – index.js

 "use strict"; const fs = require('fs'); const path = require('path'); var SampleModule = module.exports = { instAFoo: function(){ var Foo = eval.apply( this, [fs.readFileSync(path.join(__dirname, '/lib/foo.js')).toString()] ); var instance = new Foo('bar'); console.log(instance.foo); // 'bar' console.log(instance.x); // '1' } } 

希望这是有帮助的某种方式。

另一种使用node.js和express.js框架的方法

 var f1 = function(){ console.log("f1"); } var f2 = function(){ console.log("f2"); } module.exports = { f1 : f1, f2 : f2 } 

将其存储在一个名为s的js文件和文件夹静态文件中

现在使用该function

 var s = require('../statics/s'); s.f1(); s.f2(); 

我想出了一个相当粗糙的方法来处理这个HTML模板。 类似于PHP <?php include("navigation.html"); ?> <?php include("navigation.html"); ?>

server.js

 var fs = require('fs'); String.prototype.filter = function(search,replace){ var regex = new RegExp("{{" + search.toUpperCase() + "}}","ig"); return this.replace(regex,replace); } var navigation = fs.readFileSync(__dirname + "/parts/navigation.html"); function preProcessPage(html){ return html.filter("nav",navigation); } var express = require('express'); var app = express(); // Keep your server directory safe. app.use(express.static(__dirname + '/public/')); // Sorta a server-side .htaccess call I suppose. app.get("/page_name/",function(req,res){ var html = fs.readFileSync(__dirname + "/pages/page_name.html"); res.send(preProcessPage(html)); }); 

page_name.html

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>NodeJS Templated Page</title> <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css"> <!-- Scripts Load After Page --> <script type="text/javascript" src="/js/jquery.min.js"></script> <script type="text/javascript" src="/js/tether.min.js"></script> <script type="text/javascript" src="/js/bootstrap.min.js"></script> </head> <body> {{NAV}} <!-- Page Specific Content Below Here--> </body> </html> 

navigation.html

 <nav></nav> 

加载的页面结果

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>NodeJS Templated Page</title> <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css"> <!-- Scripts Load After Page --> <script type="text/javascript" src="/js/jquery.min.js"></script> <script type="text/javascript" src="/js/tether.min.js"></script> <script type="text/javascript" src="/js/bootstrap.min.js"></script> </head> <body> <nav></nav> <!-- Page Specific Content Below Here--> </body> </html>