Skip to content

Commit

Permalink
Support --require of ESM; closes #4281
Browse files Browse the repository at this point in the history
Allow files/modules specified in `--require` to be ESM.

CommonJS loading is still supported and the default.
  • Loading branch information
JacobLey committed May 27, 2020
1 parent 6d60eb0 commit 5ef04be
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 12 deletions.
13 changes: 8 additions & 5 deletions lib/cli/run-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const collectFiles = require('./collect-files');
const {type} = require('../utils');
const {format} = require('util');
const {createInvalidPluginError, createUnsupportedError} = require('../errors');
const {requireOrImport} = require('../esm-utils');

/**
* Exits Mocha when tests + code under test has finished execution (default)
Expand Down Expand Up @@ -81,15 +82,16 @@ exports.list = str =>
* @returns {Promise<MochaRootHookObject|MochaRootHookFunction>} Any root hooks
* @private
*/
exports.handleRequires = async (requires = []) =>
requires.reduce((acc, mod) => {
exports.handleRequires = async (requires = []) => {
const acc = [];
for (const mod of requires) {
let modpath = mod;
// this is relative to cwd
if (fs.existsSync(mod) || fs.existsSync(`${mod}.js`)) {
modpath = path.resolve(mod);
debug('resolved required file %s to %s', mod, modpath);
}
const requiredModule = require(modpath);
const requiredModule = await requireOrImport(modpath);
if (type(requiredModule) === 'object' && requiredModule.mochaHooks) {
const mochaHooksType = type(requiredModule.mochaHooks);
if (/function$/.test(mochaHooksType) || mochaHooksType === 'object') {
Expand All @@ -102,8 +104,9 @@ exports.handleRequires = async (requires = []) =>
}
}
debug('loaded required module "%s"', mod);
return acc;
}, []);
}
return acc;
};

/**
* Loads root hooks as exported via `mochaHooks` from required files.
Expand Down
11 changes: 4 additions & 7 deletions lib/esm-utils.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
const url = require('url');
const path = require('path');

const requireOrImport = async file => {
file = path.resolve(file);

exports.requireOrImport = async file => {
if (path.extname(file) === '.mjs') {
return import(url.pathToFileURL(file));
return import(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.
Expand All @@ -15,7 +12,7 @@ const requireOrImport = async file => {
return require(file);
} catch (err) {
if (err.code === 'ERR_REQUIRE_ESM') {
return import(url.pathToFileURL(file));
return import(file);
} else {
throw err;
}
Expand All @@ -25,7 +22,7 @@ const requireOrImport = async file => {
exports.loadFilesAsync = async (files, preLoadFunc, postLoadFunc) => {
for (const file of files) {
preLoadFunc(file);
const result = await requireOrImport(file);
const result = await exports.requireOrImport(path.resolve(file));
postLoadFunc(file, result);
}
};

0 comments on commit 5ef04be

Please sign in to comment.