Spaces:
Running
Running
const path = require('path'); | |
const url = require('url'); | |
const formattedImport = async file => { | |
if (path.isAbsolute(file)) { | |
try { | |
return await import(url.pathToFileURL(file)); | |
} catch (err) { | |
// This is a hack created because ESM in Node.js (at least in Node v15.5.1) does not emit | |
// the location of the syntax error in the error thrown. | |
// This is problematic because the user can't see what file has the problem, | |
// so we add the file location to the error. | |
// This `if` should be removed once Node.js fixes the problem. | |
if ( | |
err instanceof SyntaxError && | |
err.message && | |
err.stack && | |
!err.stack.includes(file) | |
) { | |
const newErrorWithFilename = new SyntaxError(err.message); | |
newErrorWithFilename.stack = err.stack.replace( | |
/^SyntaxError/, | |
`SyntaxError[ @${file} ]` | |
); | |
throw newErrorWithFilename; | |
} | |
throw err; | |
} | |
} | |
return import(file); | |
}; | |
exports.requireOrImport = async file => { | |
if (path.extname(file) === '.mjs') { | |
return formattedImport(file); | |
} | |
// This is currently the only known way of figuring out whether a file is CJS or ESM. | |
// If Node.js or the community establish a better procedure for that, we can fix this code. | |
// Another option here would be to always use `import()`, as this also supports CJS, but I would be | |
// wary of using it for _all_ existing test files, till ESM is fully stable. | |
try { | |
return require(file); | |
} catch (err) { | |
if (err.code === 'ERR_REQUIRE_ESM') { | |
return formattedImport(file); | |
} else { | |
throw err; | |
} | |
} | |
}; | |
exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => { | |
for (const file of files) { | |
preLoadFunc(file); | |
const result = await exports.requireOrImport(path.resolve(file)); | |
postLoadFunc(file, result); | |
} | |
}; | |