Programmatic interface for integrating ice.js into custom frameworks and toolchains. This capability allows other frameworks to leverage ice.js's CLI functionality while maintaining their own identity and adding custom commands.
Main integration function that creates a CLI instance with framework-specific configuration.
/**
* Create CLI with framework integration (module.exports function)
* @param {string} frameworkName - Name of the framework using ice.js
* @param {Object} options - Configuration options (destructured)
* @param {Object} options.packageInfo - Package.json information with required fields
* @param {Function} [options.extendCli] - Optional function to extend CLI with custom commands
* @returns {void} - Creates and runs CLI instance
*/
module.exports = function(frameworkName, { packageInfo, extendCli });Usage Examples:
const createIceCli = require("ice.js");
const packageInfo = require("./package.json");
// Basic framework integration
createIceCli("my-framework", {
packageInfo: packageInfo
});
// Framework integration with custom commands
createIceCli("my-framework", {
packageInfo: packageInfo,
extendCli: (program) => {
program
.command("deploy")
.description("deploy application")
.action(() => {
console.log("Deploying application...");
});
}
});The packageInfo object must contain specific fields for proper CLI operation:
/**
* Required package information structure (standard package.json)
* @typedef {Object} PackageInfo
* @property {string} name - Package name for display
* @property {string} version - Package version for display
* @property {Object} engines - Node.js engine requirements
* @property {string} engines.node - Node.js version requirement (e.g., ">=12.0.0")
* @property {Object} [__ICEJS_INFO__] - Ice.js framework information (auto-added)
* @property {string} [__ICEJS_INFO__.name] - Ice.js package name ("ice.js")
* @property {string} [__ICEJS_INFO__.version] - Ice.js package version ("1.18.6")
*/Example Package Info:
const packageInfo = {
name: "my-awesome-framework",
version: "2.1.0",
engines: {
node: ">=12.0.0"
},
// Optional: ice.js info will be automatically added
__ICEJS_INFO__: {
name: "ice.js",
version: "1.18.6"
}
};Optional function to extend the CLI with custom commands and functionality:
/**
* CLI extension function
* @param {Object} program - Commander.js program instance
* @returns {void} - Modify program instance to add custom commands
*/
function extendCli(program);Usage Examples:
// Add custom commands
function extendCli(program) {
program
.command("generate <type>")
.description("generate code scaffolding")
.option("-n, --name <name>", "component name")
.action((type, options) => {
console.log(`Generating ${type} with name: ${options.name}`);
});
program
.command("lint")
.description("run linting")
.option("--fix", "auto-fix issues")
.action((options) => {
console.log("Running linter...", options.fix ? "with fixes" : "");
});
}
createIceCli("my-framework", {
packageInfo: require("./package.json"),
extendCli: extendCli
});Framework integration sets up specific environment variables:
// Set by ice.js module.exports function
process.env.__FRAMEWORK_NAME__ = frameworkName;
// Set by getBuiltInPlugins function
process.env.__FRAMEWORK_VERSION__ = packageInfo.version;Environment Variable Usage:
// These variables are available throughout the build process
console.log(process.env.__FRAMEWORK_NAME__); // "my-framework"
console.log(process.env.__FRAMEWORK_VERSION__); // "1.18.6"Framework information is automatically enhanced with ice.js details:
/**
* Package info enhancement
* @param {Object} packageInfo - Original package info
* @returns {Object} Enhanced package info with __ICEJS_INFO__
*/
// Automatically adds:
packageInfo.__ICEJS_INFO__ = {
name: "ice.js",
version: "1.18.6" // from ice.js package.json
};CLI displays both framework and ice.js version information:
# With __ICEJS_INFO__ present
my-awesome-framework 2.1.0 (ice.js 1.18.6)
# Without __ICEJS_INFO__
my-awesome-framework 2.1.0Automatic Node.js version checking based on package requirements:
/**
* Node version validation
* @param {string} requiredVersion - Version requirement from packageInfo.engines.node
* @param {string} packageName - Package name for error messages
* @throws {Error} - Throws if Node.js version is incompatible
*/
checkNodeVersion(packageInfo.engines.node, packageInfo.name);All standard ice.js commands are available with framework branding:
# Standard commands work with custom framework name
my-framework start
my-framework build
my-framework test
# Custom commands added via extendCli
my-framework generate component
my-framework lint --fixFramework integration uses the same child process architecture:
/**
* Child process configuration
* @constant {string} forkChildProcessPath - Path to child process script
*/
const forkChildProcessPath = require.resolve("../bin/child-process-start");Framework-integrated CLI follows the same lifecycle:
Frameworks can provide their own plugin configurations:
const getBuiltInPlugins = require("ice.js/lib/getBuiltInPlugins");
function extendCli(program) {
// Override plugin configuration for custom commands
program
.command("custom-build")
.action(async () => {
const plugins = getBuiltInPlugins({
// Custom configuration for this framework
customFrameworkOptions: true
});
// Use plugins with custom build logic
});
}Frameworks can specify custom configuration file patterns:
function extendCli(program) {
program
.command("start")
.option("--config <config>", "use custom config", "my-framework.config.js")
.action(async (options) => {
// Use framework-specific default config
});
}Custom error handling for framework-specific operations:
function extendCli(program) {
program
.command("deploy")
.action(async () => {
try {
await deployApplication();
} catch (error) {
console.error(`${packageInfo.name} deployment failed:`, error.message);
process.exit(1);
}
});
}