This page documents the 0.4 release candidates of @nexusdi/core. The newest on npm is 0.4.0-rc.1. The documentation for 0.3.2, the current release, is at nexus.js.org. Try the release candidate.
NEXUS_OVERRIDE_EXPORTS
createTestingContainer(root).create() reports NEXUS_OVERRIDE_EXPORTS when a stub passed to overrideModule(module, stub) does not export every token and module that module exports. A module that imports the original would lose a dependency it relies on, so the testing container stops before it builds anything. create() rejects with NEXUS_BLUEPRINT_INVALID holding the error, and no call raises NEXUS_OVERRIDE_EXPORTS bare. A ship.load() that brings in a stubbed module rejects the same way when the stub lacks exports, which is how a lazy override reports it.
Reproduce NEXUS_OVERRIDE_EXPORTS
SimulatorEngineering provides REACTOR and forgets to export it. @nexusdi/testing writes this message itself, so it carries its full text and fix line with no text pack, and errors({ text }) leaves it as written.
import { Token, defineModule, isNexusError, provide } from '@nexusdi/core';
import { createTestingContainer } from '@nexusdi/testing';
interface IReactorCore {
readonly output: number;
}
const REACTOR = new Token<IReactorCore>('ReactorCore');
class FusionReactor implements IReactorCore {
readonly output = 1.21;
}
class SimulatedReactor implements IReactorCore {
readonly output = 0;
}
const Engineering = defineModule({
name: 'Engineering',
providers: [provide(REACTOR, { useClass: FusionReactor })],
exports: [REACTOR],
});
// The stub provides REACTOR and forgets to export it.
const SimulatorEngineering = defineModule({
name: 'SimulatorEngineering',
providers: [provide(REACTOR, { useClass: SimulatedReactor })],
});
const Meridian = defineModule({ name: 'Meridian', imports: [Engineering] });
const error = await createTestingContainer(Meridian)
.overrideModule(Engineering, SimulatorEngineering)
.create()
.catch((caught: unknown) => caught);
const inner = isNexusError(error, 'NEXUS_BLUEPRINT_INVALID')
? error.errors[0]
: undefined;
const lines = inner?.message.split('\n'); // -> ["[NEXUS_OVERRIDE_EXPORTS] the stub for Engineering does not export ReactorCore, which Engineering exports.", " Fix: add them to the stub's exports."]
console.log(lines?.join('\n'));Try it: run npm install @nexusdi/core@next and npm install -D @nexusdi/testing@next, save the region as stub.ts and run npx tsx stub.ts. It prints the two-line message with its Fix: line: [NEXUS_OVERRIDE_EXPORTS] the stub for Engineering does not export ReactorCore, which Engineering exports. and Fix: add them to the stub's exports. Then add exports: [REACTOR] to SimulatorEngineering and run it again. The container builds, and the region prints undefined because there is no error to read.
Fix NEXUS_OVERRIDE_EXPORTS
NEXUS_OVERRIDE_EXPORTS goes away when the stub exports everything the error lists in missing. Provide a test double for each token in the stub, and list each in its exports. The list can name modules as well as tokens, because a module that re-exports another module needs the stub to re-export it too.
import { Token, defineModule, provide } from '@nexusdi/core';
import { createTestingContainer } from '@nexusdi/testing';
interface IReactorCore {
readonly output: number;
}
const REACTOR = new Token<IReactorCore>('ReactorCore');
class FusionReactor implements IReactorCore {
readonly output = 1.21;
}
class SimulatedReactor implements IReactorCore {
readonly output = 0;
}
const Engineering = defineModule({
name: 'Engineering',
providers: [provide(REACTOR, { useClass: FusionReactor })],
exports: [REACTOR],
});
const SimulatorEngineering = defineModule({
name: 'SimulatorEngineering',
providers: [provide(REACTOR, { useClass: SimulatedReactor })],
exports: [REACTOR],
});
const Meridian = defineModule({ name: 'Meridian', imports: [Engineering] });
await using sim = await createTestingContainer(Meridian)
.overrideModule(Engineering, SimulatorEngineering)
.create();
const output = sim.get(REACTOR).output; // -> 0
console.log(output);Try it: save the region as fixed.ts and run npx tsx fixed.ts. It prints 0, the output of the simulated reactor. Delete exports: [REACTOR] from SimulatorEngineering and run it again. npx tsc accepts the file, and npx tsx fixed.ts throws an uncaught BlueprintError and prints a stack trace headed BlueprintError: [NEXUS_BLUEPRINT_INVALID] 1 error. Put the export back and the program prints 0 again.
Fields of OverrideError
code:'NEXUS_OVERRIDE_EXPORTS'or'NEXUS_OVERRIDE_UNUSED'.token:nullforNEXUS_OVERRIDE_EXPORTS.module: the name of the module the stub replaces, such as'Engineering'.missing: the names of the exports of that module that the stub lacks, as an array of strings such as['ReactorCore']. A re-exported module appears under its module name.