In Node.js, how do I “include” functions from my other files?

后端 未结 25 2459
猫巷女王i
猫巷女王i 2020-11-22 04:22

Let\'s say I have a file called app.js. Pretty simple:

var express = require(\'express\');
var app = express.createServer();
app.set(\'views\', __dirname + \         


        
相关标签:
25条回答
  • 2020-11-22 04:51

    This is the best way i have created so far.

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

    You still need to inform what you want to export

    includeOnce('./bin/WebServer.js');
    
    function Lara() {
      this.webServer = new WebServer();
      this.webServer.start();
    }
    
    Lara.prototype.webServer = null;
    
    module.exports.Lara = Lara;
    
    0 讨论(0)
  • 2020-11-22 04:53

    Another method when using node.js and express.js framework

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

    store this in a js file named s and in the folder statics

    Now to use the function

    var s = require('../statics/s');
    s.f1();
    s.f2();
    
    0 讨论(0)
  • 2020-11-22 04:54

    The vm module in Node.js provides the ability to execute JavaScript code within the current context (including global object). See http://nodejs.org/docs/latest/api/vm.html#vm_vm_runinthiscontext_code_filename

    Note that, as of today, there's a bug in the vm module that prevenst runInThisContext from doing the right when invoked from a new context. This only matters if your main program executes code within a new context and then that code calls runInThisContext. See https://github.com/joyent/node/issues/898

    Sadly, the with(global) approach that Fernando suggested doesn't work for named functions like "function foo() {}"

    In short, here's an include() function that works for me:

    function include(path) {
        var code = fs.readFileSync(path, 'utf-8');
        vm.runInThisContext(code, path);
    }
    
    0 讨论(0)
  • 2020-11-22 04:55

    Udo G. said:

    • The eval() can't be used inside a function and must be called inside the global scope otherwise no functions or variables will be accessible (i.e. you can't create a include() utility function or something like that).

    He's right, but there's a way to affect the global scope from a function. Improving his example:

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

    Hope, that helps.

    0 讨论(0)
  • 2020-11-22 04:57

    If, despite all the other answers, you still want to traditionally include a file in a node.js source file, you can use this:

    var fs = require('fs');
    
    // file is included here:
    eval(fs.readFileSync('tools.js')+'');
    
    • The empty string concatenation +'' is necessary to get the file content as a string and not an object (you can also use .toString() if you prefer).
    • The eval() can't be used inside a function and must be called inside the global scope otherwise no functions or variables will be accessible (i.e. you can't create a include() utility function or something like that).

    Please note that in most cases this is bad practice and you should instead write a module. However, there are rare situations, where pollution of your local context/namespace is what you really want.

    Update 2015-08-06

    Please also note this won't work with "use strict"; (when you are in "strict mode") because functions and variables defined in the "imported" file can't be accessed by the code that does the import. Strict mode enforces some rules defined by newer versions of the language standard. This may be another reason to avoid the solution described here.

    0 讨论(0)
  • 2020-11-22 04:57

    I just want to add, in case you need just certain functions imported from your tools.js, then you can use a destructuring assignment which is supported in node.js since version 6.4 - see node.green.


    Example: (both files are in the same folder)

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

    output: true


    This also avoids that you assign those functions as properties of another object as its the case in the following (common) assignment:

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

    where you need to call tools.isEven(10).


    NOTE:

    Don't forget to prefix your file name with the correct path - even if both files are in the same folder, you need to prefix with ./

    From Node.js docs:

    Without a leading '/', './', or '../' to indicate a file, the module must either be a core module or is loaded from a node_modules folder.

    0 讨论(0)
提交回复
热议问题