Command line interface for rapid Vue.js development
—
Comprehensive APIs for plugin development, programmatic project creation, and extending Vue CLI functionality through generators and prompt modules.
Core API provided to plugin generators for modifying projects and extending functionality.
/**
* API exposed to plugin generators for project modification and extension
*/
class GeneratorAPI {
constructor(id: string, generator: Generator, options: any, rootOptions: Preset);
/**
* Resolve path for a project relative to project root
* @param paths - Path segments to resolve
* @returns Absolute path within project
*/
resolve(...paths: string[]): string;
/**
* Assert CLI version requirement for plugin compatibility
* @param range - Semver range for required CLI version
* @throws Error if CLI version doesn't satisfy range
*/
assertCliVersion(range: number | string): void;
/**
* Assert CLI service version requirement for plugin compatibility
* @param range - Semver range for required CLI service version
* @throws Error if CLI service version doesn't satisfy range
*/
assertCliServiceVersion(range: number | string): void;
/**
* Check if the project has a given plugin
* @param id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix
* @param versionRange - Plugin version range. Defaults to '*'
* @returns Whether plugin exists and matches version range
*/
hasPlugin(id: string, versionRange?: string): boolean;
/**
* Configure how config files are extracted from package.json
* @param key - Config key in package.json
* @param options - File descriptor options for extraction
*/
addConfigTransform(key: string, options: ConfigTransformOptions): void;
/**
* Extend the package.json of the project with dependency resolution
* @param fields - Fields to merge or function returning fields
* @param options - Options for extending/merging fields
*/
extendPackage(
fields: object | ((pkg: Record<string, any>) => object),
options?: ExtendPackageOptions
): void;
/**
* Render template files into the virtual files tree object
* @param source - Template source (directory, object mapping, or middleware)
* @param additionalData - Additional data available to templates
* @param ejsOptions - Options for EJS template engine
*/
render(
source: string | RenderFile | FileMiddleware,
additionalData?: object,
ejsOptions?: object
): void;
/**
* Push a file middleware that will be applied after all normal file middlewares
* @param cb - Callback function to process files
*/
postProcessFiles(cb: PostProcessFilesCallback): void;
/**
* Push a callback to be called when the files have been written to disk
* @param cb - Callback function for completion
*/
onCreateComplete(cb: (...args: any[]) => any): void;
/**
* Same as onCreateComplete - callback for when files are written
* @param cb - Callback function for after invoke
*/
afterInvoke(cb: (...args: any[]) => any): void;
/**
* Push callback for when files have been written from non-invoked plugins
* @param cb - Callback function for after any invoke
*/
afterAnyInvoke(cb: (...args: any[]) => any): void;
/**
* Add a message to be printed when the generator exits
* @param msg - String or value to print after generation is completed
* @param type - Type of message (log, info, done, warn, error)
*/
exitLog(msg: any, type?: 'log' | 'info' | 'done' | 'warn' | 'error'): void;
/**
* Convenience method for generating a JS config file from JSON
* @param value - Value to convert to JS config
* @returns JavaScript config string
*/
genJSConfig(value: any): string;
/**
* Turn a string expression into executable JS for JS configs
* @param str - JS expression as a string
* @returns Expression function for JS configs
*/
makeJSOnlyValue(str: string): ExpressionFunction;
/**
* Run codemod on a script file or the script part of a .vue file
* @param file - Path to file to transform
* @param codemod - Codemod module to run
* @param options - Additional options for the codemod
*/
transformScript(file: string, codemod: TransformModule, options?: TransformOptions): void;
/**
* Add import statements to a file
* @param file - Target file path
* @param imports - Import statement(s) to add
*/
injectImports(file: string, imports: string | string[]): void;
/**
* Add options to the root Vue instance (detected by `new Vue`)
* @param file - Target file path
* @param options - Options to inject into root Vue instance
*/
injectRootOptions(file: string, options: string | string[]): void;
// Read-only properties
readonly cliVersion: string;
readonly cliServiceVersion: string;
readonly entryFile: 'src/main.ts' | 'src/main.js';
readonly invoking: boolean;
}Usage Examples:
// Example plugin generator using GeneratorAPI
module.exports = (api, options, rootOptions) => {
// Check CLI version compatibility
api.assertCliVersion('^5.0.0');
// Check if router plugin is installed
if (api.hasPlugin('router')) {
// Add navigation component if router exists
api.render('./templates/with-router');
} else {
// Add simple component without routing
api.render('./templates/without-router');
}
// Extend package.json with dependencies
api.extendPackage({
dependencies: {
'my-library': '^1.0.0'
},
scripts: {
'custom-command': 'my-library build'
}
});
// Add import to main entry file
api.injectImports(api.entryFile, "import MyPlugin from 'my-library'");
// Add plugin to Vue root instance
api.injectRootOptions(api.entryFile, 'MyPlugin');
// Post-process files after rendering
api.postProcessFiles((files) => {
// Modify generated files
Object.keys(files).forEach(filename => {
if (filename.endsWith('.vue')) {
files[filename] = files[filename].replace(/placeholder/g, options.replacement);
}
});
});
// Add completion message
api.exitLog('My plugin successfully installed!', 'done');
};API for creating interactive prompts during project creation.
/**
* API for plugin prompt modules to inject interactive prompts
*/
class PromptModuleAPI {
constructor(creator: Creator);
/**
* Inject checkbox choice for feature prompt during project creation
* @param feature - Checkbox choice configuration
*/
injectFeature<T = Answers>(feature: CheckboxChoiceOptions<T>): void;
/**
* Inject additional prompt into the prompt sequence
* @param prompt - Inquirer prompt configuration
*/
injectPrompt<T = Answers>(prompt: DistinctQuestion<T>): void;
/**
* Inject option for existing prompt by name
* @param name - Name of existing prompt to extend
* @param option - Choice option to add
*/
injectOptionForPrompt(name: string, option: ChoiceOptions): void;
/**
* Register callback to run when prompts are completed
* @param cb - Callback receiving answers and additional options
*/
onPromptComplete<T = Answers>(cb: OnPromptCompleteCb<T>): void;
}Usage Examples:
// Example prompt module
module.exports = (api) => {
// Add feature checkbox
api.injectFeature({
name: 'my-feature',
value: 'my-feature',
description: 'Add my custom feature',
link: 'https://example.com/docs'
});
// Add conditional prompt
api.injectPrompt({
name: 'myFeatureConfig',
when: answers => answers.features.includes('my-feature'),
type: 'list',
message: 'Choose configuration for my feature:',
choices: [
{ name: 'Basic', value: 'basic' },
{ name: 'Advanced', value: 'advanced' }
]
});
// Add option to existing prompt
api.injectOptionForPrompt('cssPreprocessor', {
name: 'My Custom CSS',
value: 'my-css'
});
// Handle prompt completion
api.onPromptComplete((answers, options) => {
if (answers.features.includes('my-feature')) {
options.plugins['my-plugin'] = {
config: answers.myFeatureConfig
};
}
});
};File generation and project setup handler.
/**
* Handles file generation and project setup coordination
*/
class Generator {
constructor(context: string, options: GeneratorOptions);
/**
* Initialize all plugins in the project
*/
async initPlugins(): Promise<void>;
/**
* Generate project files using all configured plugins
* @param options - Generation options
*/
async generate(options?: GenerateOptions): Promise<void>;
/**
* Extract configuration files from package.json to separate files
* @param extractAll - Whether to extract all configs
* @param checkExisting - Whether to check for existing config files
*/
extractConfigFiles(extractAll?: boolean, checkExisting?: boolean): void;
/**
* Sort package.json fields in standard order
*/
sortPkg(): void;
/**
* Resolve all plugins in the project
* @returns Array of resolved plugin configurations
*/
resolveAllPlugins(): PluginDescriptor[];
/**
* Resolve all file middlewares from plugins
*/
async resolveFiles(): Promise<void>;
/**
* Check if project has a specific plugin
* @param id - Plugin ID
* @param versionRange - Version range to check
* @returns Whether plugin exists
*/
hasPlugin(id: string, versionRange?: string): boolean;
/**
* Print exit log messages from plugins
*/
printExitLogs(): void;
// Properties
readonly context: string;
readonly plugins: PluginDescriptor[];
readonly pkg: PackageJson;
readonly files: RenderFile;
readonly imports: Record<string, Set<string>>;
readonly rootOptions: Record<string, Set<string>>;
}Configuration file transformation and extraction.
/**
* Handles transformation of configuration from package.json to separate files
*/
class ConfigTransform {
constructor(options: ConfigTransformOptions);
/**
* Transform configuration value to appropriate file format
* @param value - Configuration value to transform
* @param checkExisting - Whether to check for existing files
* @param files - Virtual file tree
* @param context - Project context path
* @returns Transformation result
*/
transform(
value: any,
checkExisting: boolean,
files: RenderFile,
context: string
): TransformResult;
/**
* Find existing configuration file in project
* @param files - Virtual file tree
* @returns Found file info or null
*/
findFile(files: RenderFile): FileInfo | null;
/**
* Get default configuration file name
* @returns Default file name
*/
getDefaultFile(): string;
}Type definitions for the programmatic API.
interface ConfigTransformOptions {
/** File descriptor mapping file types to filenames */
file: {
js?: string[];
json?: string[];
yaml?: string[];
lines?: string[];
};
}
interface ExtendPackageOptions {
/** Remove null or undefined fields after merging */
prune?: boolean;
/** Deep-merge nested fields */
merge?: boolean;
/** Output warning if dependency version ranges don't intersect */
warnIncompatibleVersions?: boolean;
/** Force using dependency version from first argument */
forceOverwrite?: boolean;
}
interface TransformModule {
default?: Transform;
parser?: string | Parser;
}
interface TransformOptions {
parser?: string | Parser;
[prop: string]: any;
}
interface ExpressionFunction {
(): void;
__expression: string;
}
interface RenderFile {
[path: string]: string | Buffer;
}
type FileMiddleware = (files: RenderFile, render: typeof ejs.render) => void;
type PostProcessFilesCallback = (files: RenderFile) => void;
interface OnPromptCompleteCb<T = any> {
(
answers: T,
options: {
useConfigFiles: boolean;
plugins: Record<string, any>;
}
): void;
}
interface PluginDescriptor {
id: string;
apply: GeneratorPlugin;
options: any;
}
type GeneratorPlugin = (
api: GeneratorAPI,
options: any,
rootOptions: Preset,
invoking: boolean
) => any;Helper functions for plugin development and project management.
/**
* Write virtual file tree to disk
* @param dir - Target directory
* @param files - Virtual file tree
* @param previousFiles - Previous file state for comparison
*/
async function writeFileTree(
dir: string,
files: RenderFile,
previousFiles?: RenderFile
): Promise<void>;
/**
* Generate README.md content for project
* @param pkg - Package.json content
* @param packageManager - Package manager being used
* @returns Generated README content
*/
function generateReadme(pkg: PackageJson, packageManager: string): string;
/**
* Sort object keys in consistent order
* @param obj - Object to sort
* @param keyOrder - Preferred key order
* @param dontSortByUnicode - Don't sort remaining keys by unicode
* @returns Sorted object
*/
function sortObject(
obj: Record<string, any>,
keyOrder?: string[],
dontSortByUnicode?: boolean
): Record<string, any>;
/**
* Stringify JavaScript object for config files
* @param value - Value to stringify
* @param replacer - Replacer function
* @param space - Indentation
* @returns JavaScript code string
*/
function stringifyJS(
value: any,
replacer?: (key: string, value: any) => any,
space?: string | number
): string;Install with Tessl CLI
npx tessl i tessl/npm-vue--cli