Loading a JavaScript file into another with Node.js

Without turning it into module, you can also include a file in another with functions of Node.

At command line, the JavaScript interpreter can not itself include a file in the file that it interprets, because it is designed to handle files already loaded into memory by the browser. But by using the vm module of Node to load the file we can replace the browser. Vm is a core module that you do not need to install.

For example, we want to load the extfile.js file that has the following contents:

// JavaScript Document

var extvar = "hello external"

function extfun(a, b) {
var c = a * b
return c
}

In the main file, fs and vm modules are imported, and a loading function added:

// JavaScript Document

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

var content = fs.readFileSync(filename)
vm.runInThisContext(content)

That may be reduced to a single instruction:

vm.runInThisContext(fs.readFileSync(__dirname + "/extfile.js"))

A statement which is equivalent to the PHP function include or the #include C directive.

It is then possible in the first JavaScript file to directly use the variables and functions the included file(s) contain(s):

console.log(extvar)
console.log(extfun(10, 50))

Which displays 'hello external' and '500'.

The code of the demo is included in the archive to download.

This method has two drawbacks:

  1. The file does not provide access to variables declared in the main file.
  2. You can not use the require function in the file included because vm uses V8 and therefore ignores functions of Node.
  3. So you can not use the standard library in the file included.

To access the global context, including to objects assigned by require, the eval function must be used instead:

eval(fs.readFileSync(__dirname + '/extfile.js')+'');

Which eliminates all previous limitations. Adding an empty string to the end of the code loaded by readFileSync is essential.

Using the Browser

The previous method is essential if we want to interact with the program from the command line (using fs.readSync to enter data).

If we simply want to display the results of a program, we may also skip the loading module by using the browser, and generating the results in a HTML page. The code of the main file will be like this:

<script src="extfile.js"></script>
<script>
document.write(extvar)
document.write("<br>")
document.write(extfun(10, 50))
document.write("<br>")
</script>

The included file is unchanged, unless it contains display instructions.

This second method is probably more efficient than using the vm module or eval, but requires to replace console.log by document.write.

File to include frequently

Finally, when the module to be included is to be often reused, transforming it into a module is the optimal solution. Attributes and methods must become exportable:

exports.extvar = "hello external"
exports.ext = functionf(a, b) {
var c = a * b
return c
}

The module name must be added as a prefix to use its contents:

var extfile = require("extfile.js")
console.log(extfile.extvar)
console.log(extfile.extfun(10, 50))

In conclusion, you have the choice between four options to include an external file, each better suited to each particular situation.

Download the code of the examples.

The file demovm.js is the first example with results in the command window, and demohtml.html the second with results in an HTML file.