Welcome to the first chapter of our deep dive into the reload-plugins project! We are going to build an understanding of how a complex CLI application manages its features efficiently.
Imagine you walk into a massive restaurant. The menu has hundreds of options: burgers, sushi, pasta, tacos, and more.
If the kitchen started cooking every single dish the moment the restaurant opened, just in case someone ordered it, two things would happen:
Instead, a restaurant uses a Menu. The menu is just a list of names and descriptions. The kitchen only starts cooking a specific dish when you actually order it.
In software, we call this Lazy Loading.
We want to create a command called /reload-plugins.
/reload-plugins.To solve this, we split our feature into two files:
index.ts): A tiny file that describes the command.reload-plugins.ts): The heavy file containing the actual code.
Let's look at how we define the "Menu Item" for our command. This happens in index.ts.
We define a lightweight object. Notice we aren't writing the logic here; we are just describing it.
// index.ts
import type { Command } from '../../commands.js'
const reloadPlugins = {
type: 'local',
name: 'reload-plugins',
description: 'Activate pending plugin changes in the current session',
// ... extra metadata ...
} satisfies Command
name: This is what the user types (e.g., /reload-plugins).description: What shows up in the help menu.
Here is the most important part. Instead of importing the logic at the top of the file, we use a load function.
// index.ts (continued)
const reloadPlugins = {
// ... previous properties ...
// This function is ONLY called when the user runs the command
load: () => import('./reload-plugins.js'),
} satisfies Command
export default reloadPlugins
load: This is a function that returns a Promise.import(...): This tells the runtime to go find the file ./reload-plugins.js and load it into memory right now. Before this line runs, the heavy file effectively doesn't exist to the application.
When you type /reload-plugins, the system goes through a specific flow to ensure it only does work when necessary.
/reload-plugins.reload-plugins.load() function and executes it.reload-plugins.ts from the disk.call function exported by that file.
Now that the file has been loaded, let's look at the "Kitchen" logic in reload-plugins.ts. This file exports a specific function named call that the application knows how to run.
This function receives arguments and context (like the current state of the app).
// reload-plugins.ts
import type { LocalCommandCall } from '../../types/command.js'
// ... other imports ...
export const call: LocalCommandCall = async (_args, context) => {
// Logic to sync settings and refresh plugins goes here...
// ...
}
The command doesn't just run silently; it returns a result to show to the user.
// reload-plugins.ts (continued)
// ... inside call() ...
// Create a success message
let msg = `Reloaded: ${parts.join(' ยท ')}`
// Return the output to the UI
return { type: 'text', value: msg }
}
Inside this call function, we perform several heavy operations that we avoided loading at startup.
In this chapter, you learned how to use Command Architecture and Lazy Loading to keep your application fast. By separating the definition (index.ts) from the implementation (reload-plugins.ts), we ensure that the "Kitchen" only gets messy when someone actually orders a meal.
Once the command is loaded and running, the very first thing it needs to do is ensure it has the latest rules and settings from the server.
Next Chapter: Remote Settings Synchronization
Generated by Code IQ