有些情况下,我在单个js文件环境中工作,例如Grease Monkey脚本,我想添加一个节点测试运行程序(mocha(。Js非常灵活,可以处理这两种环境。做一些类似的事情:
if (typeof module !== 'undefined') {
module.exports = {
myFunctionToTest
}
} else {
// Code to be executed in the real environment
}
function myFunctionToTest () {
}
这种方法很好,因为我可以简单地在另一个文件中用mocha编写测试:
const {myFunctionToTest} = require('./source.js')
describe('My test', // ...
但我也可以将脚本复制粘贴到单个js环境中。
我面临的问题是,我想在一个允许顶级等待的环境中做类似的事情。如果我尝试执行前面的示例,我会得到一个SyntaxErrorSyntaxError: await is only valid in async function
。当然,node允许使用标志--experimental-top-level-await
进行顶级等待,但这需要代码处于模块模式。模块模式不允许模块导出。
在模块模式下有没有一种方法可以进行动态导出,以避免在其他js环境中出现语法问题?还是为了避免代码分支中未执行的等待语法错误?
穷人的解决方案是伪造捆绑器:
let functionToTest
beforeEach(async function () {
const moduleCode = fs.readFileSync('./myscript.js').toString()
const myFunctionCode = `async function myFunction (module) { ${moduleCode}}`
eval(myFunctionCode)
const fakeModule = {}
await myFunction(fakeModule)
functionToTest = fakeModule.exports.functionToTest
})