我有一个像这样的模块:

var hello = 'Hello Sir'

console.log(hello)


我想在另一个文件中要求该模块rewire,但是当我这样做时,它将执行hello world。在执行模块之前,有什么方法可以重新接线吗?

babel-plugin-rewire尝试

var g = require('./global.js')
g.__Rewire__('hello', 'Hello Madam')


因为它使用require并且不导出任何内容,所以它仅执行,而g没有任何值。

proxyquire尝试

似乎proxyquire允许我更改全局hello变量,但前提是必须将其隐藏到模块调用中。

const proxyquire = require('proxyquire')
proxyquire('./global', {'./hello': 'Hello Madam'})


sandboxed-module尝试

该模块似乎可以设置globalslocals,但是不能覆盖模块中的现有值。

const SandboxedModule = require('sandboxed-module')
SandboxedModule.require('./global', {
  globals: {hello: 'hello Madam'}
})

最佳答案

听起来您想在读取模块后在运行时将“ Hello Sir”动态更改为“ Hello World”,对吗?

一种方法是不使用require以纯文本形式读取模块,并使用类似recast的工具将其转换为Abstract-Syntax Tree

一旦成为AST,您就可以按照自己喜欢的任何方式对其进行修改,并使用eval动态执行。

hello.js

var hello = 'Hello Sir'

console.log(hello)


recast.js

const recast = require("recast");
const fs = require('fs');

// read the file in as plain text
const code = fs.readFileSync('./hello.js');

// create abstract syntax tree
const ast = recast.parse(code);

// change value of the first variable
ast.program.body[0].declarations[0].init.value = 'Hello World';

// convert AST back to Javascript text
const modifiedSrc = recast.print(ast).code;

// execute modified code
eval(modifiedSrc);


从命令行执行

~/example$ node recast.js
Hello World

关于node.js - 需要并覆盖模块作用域变量以进行测试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49478755/

10-14 17:52
查看更多