CLI Plugin API
Modern.js's CLI plugins allow you to extend and customize the functionality of Modern.js projects during the build and development process.
CLI plugins need to be configured via the plugins field in modern.config.ts.
Plugin Basic Structure
A typical CLI plugin structure is as follows:
name: A unique identifier for the plugin.- The
setupfunction receives anapiobject, which provides all available CLI plugin APIs.
Information Retrieval
api.getAppContext
Gets the context information of the Modern.js application.
- Returns: An
AppContextobject containing the following fields:
- Example:
The context information returned by getAppContext is read-only and cannot be modified directly.
api.getConfig
Gets the user-defined configuration from the modern.config.ts file.
- Returns: The user-defined configuration object.
- Example:
api.getNormalizedConfig
Gets the final configuration after internal processing by Modern.js and modifications by plugins (normalized configuration).
- Returns: The normalized configuration object.
- When Available: Must be used in
onPrepare(and later hooks, such asonBeforeBuild). - Example:
api.isPluginExists
Checks if a specified plugin is registered.
- Parameters:
pluginName: string: The name of the plugin to check.
- Returns: A
booleanvalue indicating whether the plugin exists. - Example:
api.getHooks
Gets all registered hook functions.
- Returns: An object containing all hook functions.
- Example:
In custom plugins, you can only manually call the hooks registered by the corresponding plugin and cannot call official hooks to avoid affecting the normal execution order of the application.
Configuration Modification
api.config
Modify the initial configuration of Modern.js.
- Type:
api.config(configFn: () => UserConfig | Promise<UserConfig>) - Parameters:
configFn: A function that returns a configuration object or a Promise.
- Execution Phase: After parsing the configuration in
modern.config.ts. - Example:
Configuration Merging Priority (from highest to lowest):
- Configuration defined by the user in the
modern.config.*file. - Configuration registered by plugins via
api.config(). - Default Modern.js configuration.
api.modifyBundlerChain
Modify Rspack configuration using the chain API.
- Type:
api.modifyBundlerChain(modifyFn: (chain: RspackChain, utils: RspackUtils) => void | Promise<void>) - Parameters:
modifyFn: A modification function that receives aRspackChaininstance and utility functions as parameters.
- Execution Phase: When generating the final Rspack configuration.
- Corresponding Rsbuild Hook: modifyBundlerChain
- Example:
api.modifyRsbuildConfig
Modify the Rsbuild configuration.
- Type:
api.modifyRsbuildConfig(modifyFn: (config: RsbuildConfig, utils: RsbuildUtils) => RsbuildConfig | Promise<RsbuildConfig> | void) - Parameters:
modifyFn: A modification function that receives the Rsbuild configuration object and utility functions as parameters. It can return the modified configuration object, a Promise, or nothing (modifying the original object directly).
- Execution Phase: When generating the final Rsbuild configuration.
- Corresponding Rsbuild Hook: modifyRsbuildConfig
- Example:
api.modifyRspackConfig
Modify the Rspack configuration (when using Rspack as the bundler).
- Type:
api.modifyRspackConfig(modifyFn: (config: RspackConfig, utils: RspackUtils) => RspackConfig | Promise<RspackConfig> | void) - Parameters:
modifyFn: A modification function that receives the Rspack configuration object and utility functions as parameters. It can return the modified configuration object, a Promise, or nothing (modifying the original object directly).
- Execution Phase: When generating the final Rspack configuration.
- Corresponding Rsbuild Hook: modifyRspackConfig
- Example:
Build Configuration Modification Order
api.modifyServerRoutes
Modify the server routing configuration.
- Type:
api.modifyServerRoutes(transformFn: (routes: ServerRoute[]) => ServerRoute[]) - Parameters:
transformFn: A transformation function that receives the current server routes array as a parameter and returns the modified array.
- Execution Phase: Before generating the server route file (during the
preparephase). - Example:
api.modifyHtmlPartials
Modify HTML template partials.
- Type:
api.modifyHtmlPartials(modifyFn: (partials: HtmlPartials, entrypoint: Entrypoint) => void) - Parameters:
modifyFn: A modification function that receives the HTML template partials object and the current entry point information as parameters.partials: Containstop,head, andbodysections, each withappend,prepend, andreplacemethods.
- Execution Phase: Before generating the HTML file (during the
preparephase). - Example:
This hook function will not be executed when using a completely custom HTML template.
Build Process Control
api.onPrepare
Add additional logic during the Modern.js preparation phase.
- Type:
api.onPrepare(prepareFn: () => void | Promise<void>) - Parameters:
prepareFn: A preparation function, without parameters, can be asynchronous.
- Execution Phase: After Modern.js has completed configuration validation.
- Example:
api.addCommand
Add a custom CLI command.
- Type:
api.addCommand(commandFn: ({ program: Command }) => void) - Parameters:
commandFn: Receives theprogramobject fromcommanderas a parameter, used to define new commands.
- Execution Phase: After the
preparehook has completed. - Example:
api.addWatchFiles
Add additional files to the watch list (for development mode).
- Type:
api.addWatchFiles(watchFn: () => string[] | { files: string[]; isPrivate: boolean; }) - Parameters:
watchFn: Returns an array of file paths or an object containingfilesandisPrivateproperties.files: An array of file paths to watch.isPrivate: Whether the files are framework-internal (affects behavior when files change).
- Execution Phase: After the
addCommandhook has completed. - Example:
api.onFileChanged
Add additional logic when a watched file changes (for development mode).
- Type:
api.onFileChanged(changeFn: (params: { filename: string; eventType: 'add' | 'change' | 'unlink'; isPrivate: boolean; }) => void) - Parameters:
changeFn: A file change handler function that receives the following parameters:filename: The path of the changed file.eventType: The type of change (add,change,unlink).isPrivate: Whether the file is framework-internal.
- Execution Phase: After a watched file changes.
- Example:
api.onBeforeBuild
Add additional logic before the build starts.
- Type:
api.onBeforeBuild(buildFn: () => void | Promise<void>) - Parameters:
buildFn: A function to be executed before the build, without parameters, can be asynchronous.
- Execution Phase: Before executing the build process.
- Corresponding Rsbuild Hook: onBeforeBuild
- Example:
api.onAfterBuild
Add additional logic after the build is complete.
- Type:
api.onAfterBuild(buildFn: () => void | Promise<void>) - Parameters:
buildFn: A function to be executed after the build, without parameters, can be asynchronous.
- Execution Phase: After executing the build process.
- Corresponding Rsbuild Hook: onAfterBuild
- Example:
api.onDevCompileDone
Add additional logic after the development server compilation is complete.
- Type:
api.onDevCompileDone(compileFn: () => void | Promise<void>) - Parameters:
compileFn: A function to be executed after compilation is complete.
- Execution Phase: After the development server starts and the initial compilation is complete.
- Corresponding Rsbuild Hook: onDevCompileDone
- Example:
api.onBeforeCreateCompiler
Add additional logic before creating the compiler instance.
- Type:
api.onBeforeCreateCompiler(createFn: () => void | Promise<void>) - Parameters:
createFn: A function to be executed before creation, without parameters, can be asynchronous.
- Execution Phase: Before creating the Rspack compiler instance.
- Corresponding Rsbuild Hook: onBeforeCreateCompiler
- Example:
api.onAfterCreateCompiler
Add additional logic after creating the compiler instance.
- Type:
api.onAfterCreateCompiler(createFn: () => void | Promise<void>) - Parameters:
createFn: A function to be executed after creation, without parameters, can be asynchronous.
- Execution Phase: After creating the Rspack compiler instance.
- Corresponding Rsbuild Hook: onAfterCreateCompiler
- Example:
api.onBeforeDev
Add additional logic before starting the development server.
- Type:
api.onBeforeDev(devFn: () => void | Promise<void>) - Parameters:
devFn: A function to be executed before starting the development server, without parameters, can be asynchronous.
- Execution Phase: Before executing the
devcommand to start the development server. - Example:
api.onAfterDev
Add additional logic after starting the development server.
- Type:
api.onAfterDev(devFn: () => void | Promise<void>) - Parameters:
devFn: A function to be executed after the development server starts.
- Execution Phase: After the development server has successfully started.
- Corresponding Rsbuild Hook: onAfterStartDevServer
- Example:
api.onBeforeExit
Add additional logic before the process exits.
- Type:
api.onBeforeExit(exitFn: () => void | Promise<void>) - Parameters:
exitFn: A function to be executed before the process exits, without parameters, can be asynchronous.
- Execution Phase: When the Modern.js process is about to exit (for example, when the user presses Ctrl+C).
- Example:
api.onBeforePrintInstructions
Add additional logic before printing success information.
- Type:
api.onBeforePrintInstructions(printFn: ({instructions: string}) => {instructions: string} | Promise<{instructions: string}>) - Parameters:
printFn: Function to modify the printed information, returns the modified information.
- Execution Phase: Before printing success information.
- Example:
Other Notes
- Refer to CLI Plugin Lifecycle to understand the execution order of plugin hooks.