Welcome back! In Chapter 3: Lazy Module Loading, we set up a system to efficiently load our heavy code only when needed.
Now that the code is loaded into memory, we face a new question: How do we actually run it?
Specifically, how do we run a command that isn't just a simple script, but a full interactive interface? This brings us to the Local JSX Command Handler.
The Central Use Case:
Most simple CLI commands are "Fire and Forget." You type echo "hello", the computer prints "hello", and the program ends immediately.
But our doctor command is different. It needs to:
We need a standard wayβa specific patternβto connect the raw CLI environment to our React components. We need a bridge.
To build this bridge, we use three concepts:
call Function: This is the entry point. When the CLI loads your file, it looks for a specifically named function called call to start the work.<MyComponent />).onDone Callback: Since the interface is interactive, the CLI doesn't know when to quit. We must pass it a function ("Call this when you are finished") so the UI can control the exit.
In the previous chapter, we told the CLI to import ./doctor.js. Now, let's look at the code inside that file (specifically doctor.tsx).
We will implement the bridge in two small steps.
First, we import the necessary tools. We need React, the UI component we want to show, and the type definition to ensure our code follows the rules.
// src/commands/doctor/doctor.tsx
import React from 'react';
import { Doctor } from '../../screens/Doctor.js';
import type { LocalJSXCommandCall } from '../../types/command.js';
Explanation: We are preparing to render the <Doctor /> screen. This screen contains the actual UI logic (which we will build in the next chapter).
call)
This is the most important part. We export a constant named call. The CLI framework calls this function automatically.
export const call: LocalJSXCommandCall = (onDone, _context, _args) => {
// We return a Promise that resolves to our React Component
return Promise.resolve(<Doctor onDone={onDone} />);
};
Explanation:
onDone. This is the "Exit Button" trigger.<Doctor /> component.onDone={onDone}. We are passing the "Exit Button" down into the visual component. This allows the UI to decide when the program finishes.How does a text command transform into a React component?
load() function (from Chapter 3).call export.call and "mounts" it to the terminal standard output, taking over the screen.onDone.
While you only need to write the call function, it helps to understand what the CLI system does with it.
The system treats local-jsx commands differently than standard scripts. It expects a return value that looks like a UI Element.
// Pseudo-code of what the CLI framework does internally
async function runCommand(commandDef) {
// 1. Load the module
const module = await commandDef.load();
// 2. Define the exit strategy
const onDone = () => {
process.exit(0); // Quit the program
};
// 3. Get the component from the handler
const uiComponent = await module.call(onDone);
// 4. Render it using a library (like Ink)
render(uiComponent);
}
Explanation:
The complexity of setting up the React reconciler and managing the terminal output is hidden from you. As a developer, your contract is simple: Export a call function, return a Component, and use onDone.
In this chapter, we learned about the Local JSX Command Handler.
This pattern acts as a connector. It takes the execution signal from the CLI and translates it into a React Component tree. Crucially, it handles the application lifecycle by passing down an onDone callback, giving our interactive UI the power to decide when the work is complete.
Now that our handler is successfully mounting the <Doctor /> component, we need to actually build that component!
In the final chapter, we will write the React code that displays the diagnosis interface.
Next Chapter: Screen Component Integration
Generated by Code IQ