resolve = (spec, referrer) => {
  spec = String(spec || '');
  referrer = String(referrer || '');

  if (spec.startsWith('/')) {
    throw Error(`Module specifier ${q(spec)} must not begin with "/"`);
  }
  if (!referrer.startsWith('./')) {
    throw Error(`Module referrer ${q(referrer)} must begin with "./"`);
  }

  const specParts = spec.split('/');
  const solution = [];
  const problem = [];
  if (specParts[0] === '.' || specParts[0] === '..') {
    const referrerParts = referrer.split('/');
    problem.push(...referrerParts);
    problem.pop();
    solution.push('.');
  }
  problem.push(...specParts);

  if (!solve(solution, problem)) {
    throw Error(
      `Module specifier ${q(spec)} via referrer ${q(
        referrer,
      )} must not traverse behind an empty path`,
    );
  }

  return solution.join('/');
}
`Resolve` computes the full module specifier for a given imported module specifier
relative to the referrer module specifier.
In Node.js compartments, the referrer must be an internal module specifier
in the context of a compartment, and all internal module specifiers begin
with a "." path component.
The referent may be either internal or external.
In Node.js, fully resolved paths are valid module specifiers, but these
paths that begin with / are disallowed as they could be used to defeat
compartment containment.

@param {string} spec - a path to resolve.
@param {string} referrer - the fully resolved path of referrer module.
@returns {string} the fully resolved path.