Skip to content Skip to sidebar Skip to footer

Load Text As Javascript Object In Node.js

I have a javascript file for node.js: module.exports = { someString: 'blblalb' } I want to able to read the file as a javascript object, using fs.readFileSync. I can't use re

Solution 1:

You can use eval('JavaScript string') but is highly recommended not to. It is a serious security risk if you cannot 100% trust the source of the text. If a malicious user figures out a way to modify the text they have complete control of your system. It is not a path I would take or recommend.

const text = 'console.log("Hello")';

eval(text);

If I saw that code when I was doing a code review we would definitely be having some words.

Solution 2:

it's possible to evaluate a file or string variable as child module in hacky yet valid way.

The problem is that Node.js module environment should be unaware of these operations. Child module may load other modules and contain require(...), it will fail if there is no require function (there is none if it is evaluated with vm) or it uses wrong module relative path (this will happen with eval), also there will be no dedicated module.exports for a module. This can be fixed by wrapping module source with Node.js module wrapper that was rewired to match child module location.

const fs = require('fs');
constModule = require('module');
const path = require('path');

const childModuleAbsPath = path.resolve('./foo/bar.js');
const childModuleBody = fs.readFileSync(childModuleAbsPath);
const childModuleObj = { exports: {} };
const { dir: childModuleDirname, base: childModuleFilename } = path.parse(childModuleAbsPath);
constchildRequire = modulePath => module.require(childModuleAbsPath);

require('vm').runInThisContext(Module.wrap(childModuleBody))(
  childModuleObj.exports,
  childRequire,
  childModuleObj,
  childModuleDirname,
  childModuleFilename
);

In this case childModuleObj.exports.someString === 'blblalb' after bar child module was evaluated.

This is XY problem that should be addressed in another way.

If the intention is to reevaluate a module with new variables, this can be done by invalidating Node module cache by modifying require.cache, e.g. with decache:

decache('./foo/bar');
const reloadedBar = require('./foo/bar');

Post a Comment for "Load Text As Javascript Object In Node.js"