A lightweight proxy API for accessing @microsoft/rush-lib with smart loading and version resolution
—
Advanced loader API for explicit control over Rush engine loading with progress monitoring and cancellation support.
Main loader class that provides explicit control over when and how the Rush engine is loaded.
/**
* Provides operations that control how the @microsoft/rush-lib engine is located and loaded
*/
class RushSdkLoader {
/** Returns true if the Rush engine has already been loaded */
static readonly isLoaded: boolean;
/**
* Manually load the Rush engine based on rush.json found for rushJsonSearchFolder
* Throws an exception if isLoaded is already true
*/
static loadAsync(options?: ILoadSdkAsyncOptions): Promise<void>;
}Usage Examples:
import { RushSdkLoader } from "@rushstack/rush-sdk/loader";
// Basic loading
if (!RushSdkLoader.isLoaded) {
await RushSdkLoader.loadAsync();
}
// Load from specific folder
await RushSdkLoader.loadAsync({
rushJsonSearchFolder: "/path/to/my-repo/apps/my-app"
});
// With progress monitoring
await RushSdkLoader.loadAsync({
rushJsonSearchFolder: process.cwd(),
onNotifyEvent: (event) => {
if (event.logMessage) {
console.log(event.logMessage.text);
}
if (event.progressPercent !== undefined) {
console.log(`Progress: ${event.progressPercent}%`);
}
}
});
// After loading, use regular Rush SDK APIs
const rushSdk = require("@rushstack/rush-sdk");
const config = rushSdk.RushConfiguration.loadFromDefaultLocation();Configuration options for the manual loading process.
/**
* Options for RushSdkLoader.loadAsync
*/
interface ILoadSdkAsyncOptions {
/**
* The folder to start from when searching for rush.json
* If not found, each parent folder will be searched
* Defaults to process.cwd()
*/
rushJsonSearchFolder?: string;
/**
* A cancellation token that the caller can use to abort the operation
*/
abortSignal?: AbortSignal;
/**
* Allows the caller to monitor the progress of the operation
*/
onNotifyEvent?: SdkNotifyEventCallback;
}
/**
* Callback function type for progress notifications
*/
type SdkNotifyEventCallback = (sdkEvent: ISdkCallbackEvent) => void;Usage Examples:
import { RushSdkLoader } from "@rushstack/rush-sdk/loader";
// With cancellation support
const abortController = new AbortController();
setTimeout(() => abortController.abort(), 30000); // Cancel after 30 seconds
try {
await RushSdkLoader.loadAsync({
rushJsonSearchFolder: "/path/to/repo",
abortSignal: abortController.signal,
onNotifyEvent: (event) => {
if (event.logMessage?.kind === 'info') {
console.log(`INFO: ${event.logMessage.text}`);
}
}
});
} catch (error) {
if (error.name === 'AbortError') {
console.log('Loading was cancelled');
} else {
throw error;
}
}Event data provided during the loading process for monitoring and user feedback.
/**
* Event data for onNotifyEvent callback
*/
interface ISdkCallbackEvent {
/**
* Log message to display, or undefined if no message
*/
logMessage: IProgressBarCallbackLogMessage | undefined;
/**
* Progress percentage (0-100) if a long-running operation is active,
* undefined if no progress tracking is available
*/
progressPercent: number | undefined;
}
/**
* Log message structure
*/
interface IProgressBarCallbackLogMessage {
/** The message text, may contain newlines */
text: string;
/** The type of message */
kind: "info" | "debug";
}Usage Examples:
import { RushSdkLoader, ISdkCallbackEvent } from "@rushstack/rush-sdk/loader";
// Advanced progress monitoring
function displayProgress(event: ISdkCallbackEvent): void {
if (event.logMessage) {
const prefix = event.logMessage.kind === 'info' ? '[INFO]' : '[DEBUG]';
console.log(`${prefix} ${event.logMessage.text}`);
}
if (event.progressPercent !== undefined) {
const progressBar = '='.repeat(Math.floor(event.progressPercent / 2));
const spaces = ' '.repeat(50 - progressBar.length);
console.log(`[${progressBar}${spaces}] ${event.progressPercent.toFixed(1)}%`);
}
}
await RushSdkLoader.loadAsync({
onNotifyEvent: displayProgress
});The Rush SDK supports five different loading scenarios:
Rush's PluginManager pre-initializes the SDK with its own instance. The global variable ___rush___rushLibModule is set before loading plugins.
Projects with @microsoft/rush-lib in devDependencies will use their local instance for testing.
Tools invoked by Rush inherit the installation via the _RUSH_LIB_PATH environment variable.
Scripts and tools automatically discover Rush via rush.json and use install-run-rush.js to load the appropriate version.
Explicit control using RushSdkLoader.loadAsync() with full progress monitoring and cancellation support.
import { RushSdkLoader } from "@rushstack/rush-sdk/loader";
try {
await RushSdkLoader.loadAsync({
rushJsonSearchFolder: "/invalid/path"
});
} catch (error) {
if (error.name === 'AbortError') {
console.log('Operation was cancelled');
} else if (error.message.includes('Unable to find rush.json')) {
console.log('Not in a Rush workspace');
} else if (error.message.includes('failed to install')) {
console.log('Failed to install Rush engine');
} else {
console.log(`Unexpected error: ${error.message}`);
}
}Enable verbose logging by setting environment variables:
# Enable debug logging
export RUSH_SDK_DEBUG=1
# Alternative debug flag
export _RUSH_SDK_DEBUG=1When debug logging is enabled, detailed information about the loading process will be printed to the console, including which scenario is being used and how the Rush engine was located.
Install with Tessl CLI
npx tessl i tessl/npm-rushstack--rush-sdk