Welcome to the final chapter of the files project tutorial!
Let's quickly recap our journey:
Now, imagine we have 100 different chefs for 100 different dishes. If all 100 chefs try to squeeze into the kitchen the moment we open the restaurant, nobody can move! The restaurant (your application) becomes slow and clunky.
This chapter introduces the Lazy Loading Mechanism, which keeps our kitchen empty and fast until an order is actually placed.
In traditional programming, you often see a long list of imports at the top of a file:
// The "Eager" way (Bad for performance)
import { call as fileCall } from './files.js'
import { call as networkCall } from './network.js'
import { call as databaseCall } from './database.js'
// ... imagine 50 more lines here
When you start the application, the computer has to read, load, and compile all of these files immediately, even if the user only wants to check the time. This is called "Eager Loading," and it makes applications slow to start and heavy on memory.
We use a technique similar to "Just-in-Time" manufacturing.
Think of a Car Factory.
In our code, we tell the system: "Here is the address of the code file, but don't go get it until the user actually types the command."
import ... from ... at the top of a file. happens immediately.import(...) used inside a function. It returns a Promise. It happens only when that line of code is executed.load Property
In Chapter 1, we saw the load property in our registration object. This is our specific trigger.
Let's look at index.ts again. We are defining the command, but notice we are not importing the logic at the top.
import type { Command } from '../../commands.js'
// Notice: No import of './files.js' here!
const files = {
type: 'local',
name: 'files',
description: 'List all files currently in context',
// ... checks and flags
// THE MAGIC HAPPENS HERE:
load: () => import('./files.js'),
} satisfies Command
export default files
Explanation:
load: This is a function.() => ...: This function is not run when the file is read. It sits there, waiting.import('./files.js'): This command fetches the code from the other file. It creates a bridge to the logic we wrote in Chapter 4.index.ts. It takes up almost zero memory because it's just text descriptions.load() function.files.js, compiles it, and loads it into memory.The system has a "Runner" that orchestrates this. It acts like a dispatcher.
Here is the flow of a user triggering a Lazy Loaded command.
Let's write a simplified version of the system code that actually calls your command. This helps you understand why we defined load the way we did.
The system has a list of registered commands (the menus).
// simplified_runner.ts
async function runUserCommand(inputName: string, context: any) {
// 1. Find the registration object (from Chapter 1)
const commandDef = registry.find(cmd => cmd.name === inputName)
if (!commandDef) return "Command not found"
// ... continued below
}
This is where the dynamic import is triggered. We use await because reading a file from disk takes a few milliseconds.
// ... continued
// 2. Load the implementation (The Lazy Load)
// We call the function we defined in index.ts
const module = await commandDef.load()
// 'module' now holds the contents of 'files.ts'
// specifically, it holds the 'call' function
Now that we have the module, we can run the call function we wrote in Chapter 4.
// ... continued
// 3. execute the logic
const result = await module.call(null, context)
return result
}
As a developer adding a new feature to files:
files.ts has a syntax error, the app will still start successfully. The error will only crash if someone tries to run that specific command.In this final chapter, we learned:
() => import(...) to create a bridge between the definition and the logic.
You have now completed the entire architecture tutorial for the files project!
You are now ready to build your own commands and extend the system. Happy coding!
Generated by Code IQ