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

1219

假设我有一个名为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"转换为一个模块,然后进行 require 吗? << 这似乎很困难,我宁愿进行 tools.js 文件的基本导入。


5
在Windows系统中,我感到困惑的是使用require引入同一目录下的文件夹。你需要使用类Unix风格的路径表示方式:使用./mydir而不是简单的mydir - Ben
1
我创建了一个模块,可以导入脚本,将其导出到文件,并从node_modules文件夹外部包含模块。https://www.npmjs.com/package/node-import 希望它能有所帮助。谢谢! - Nanang Mahdaen El-Agung
29个回答

14

Udo G.说:

  • eval()不能在函数内部使用,必须在全局范围内调用,否则函数或变量将不可访问(即您无法创建一个 include() 实用程序函数或类似功能)。

他是对的,但有一种方法可以从函数中影响全局范围。改进他的例子:

function include(file_) {
    with (global) {
        eval(fs.readFileSync(file_) + '');
    };
};

include('somefile_with_some_declarations.js');

// the declarations are now accessible here.

希望这能有所帮助。


12

它对我起了以下的作用...

Lib1.js

//Any other private code here 

// Code you want to export
exports.function1 = function(params) {.......};
exports.function2 = function(params) {.......};

// Again any private code

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

var mylib = requires('lib1.js');
mylib.function1(params);
mylib.function2(params);
请记得将Lib1.js放在node_modules文件夹中。

12

app.js

let { func_name } = require('path_to_tools.js');
func_name();    //function calling

工具.js

let func_name = function() {
    ...
    //function body
    ...
};

module.exports = { func_name };

11

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

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()时,请注意未定义的变量,如果使用 eval() 加载也是一样的。希望能有所帮助 :)


10

如果您只需要从tools.js中导入某些特定函数,那么您可以使用解构赋值。自Node.js版本6.4起支持该功能,请参见node.green


示例(两个文件位于同一文件夹中)

tools.js

module.exports = {
    sum: function(a,b) {
        return a + b;
    },
    isEven: function(a) {
        return a % 2 == 0;
    }
};

main.js

const { isEven } = require('./tools.js');

console.log(isEven(10));

输出: true


这还可以避免您将这些函数分配为另一个对象的属性,如下面(通常)的分配所示:

const tools = require('./tools.js');

在这种情况下,您需要调用 tools.isEven(10)


注意:

不要忘记以正确的路径前缀文件名 - 即使两个文件都在同一个文件夹中,您也需要以 ./ 为前缀

来自Node.js文档:

如果没有前导'/', './'或'../'表示文件,则模块必须是核心模块,否则会从node_modules文件夹加载。


10

您可以将函数放入全局变量中,但最好的做法是将工具脚本转换为模块。这并不太难 - 只需将公共API附加到exports对象即可。请查看了解 Node.js' exports 模块获取更多细节。


5
例子胜于链接。 - tno2007

3

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

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);

3
使用ESM模块系统:
a.js:
export default function foo() {};

export function bar() {};

b.js:

import foo, {bar} from './a.js';

1
我认为最干净的方法是在tools.js中使用以下方法:
function A(){
.
.
.
}

function B(){
.
.
.
}

module.exports = {
A,
B
}

然后,在 app.js 中,只需按照以下方式 require tools.js:

const tools = require("tools"); 请注意保留 HTML 标签。

1
这是我目前为止创建的最佳方式。
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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接