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.

Classic methods

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:

let extvar = "Hello World"

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

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

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

let 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 World!" and "500".

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.

Modern method

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 World!"
exports.extfun = function(a, b) {
  let c = a * b
  return c
} 

This script is stored in the extfile.js file, in the modules subdirectory. This is not mandatory; you can place it wherever you want...

Then we import the module and we use the module name "extfile" as a prefix to use its contents:

import * as extfile from "./modules/extfile.js";
console.log(extfile.extvar)
console.log(extfile.extfun(10, 50))

That will display :

Hello World!
500

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