Overview and Usage of the Hvigor Build Tool for HarmonyOS Development
Hvigor is a TypeScript‑based build orchestration tool for HarmonyOS that manages tasks, project models, and configurations, integrates with DevEco Studio for consistent command‑line and IDE builds, supports lifecycle phases, custom tasks, plugins, and routing plugins, and provides detailed development guides and code examples.
Hvigor is a build orchestration tool implemented in TypeScript, designed to improve the efficiency of building and testing HarmonyOS applications. Its core features include a task management mechanism, project model management, and flexible configuration management.
Integration with DevEco Studio : DevEco Studio uses Hvigor to automate and manage the build process, enabling both IDE‑based and command‑line builds. Hvigor offers automated build workflows and can run independently on CI servers, ensuring developers can work in various environments without IDE lock‑in.
Build Consistency : Whether using the command line or DevEco Studio, the output remains identical, reducing environment‑related issues.
Typical Usage Scenarios include local development within DevEco Studio, command‑line builds, and CI/CD pipelines where Hvigor runs as an independent build tool.
Supported Languages : Hvigor supports mainstream front‑end languages such as TypeScript and JavaScript.
Build Lifecycle consists of three phases—initialization, configuration, and execution:
1. Initialization : Constructs a directed acyclic graph of task dependencies, builds a tree‑structured project model, sets build parameters from command‑line arguments and hvigor-config.json5 , detects configuration files, creates node descriptors, and executes the hvigorconfig.ts file.
2. Configuration : Loads plugins and tasks for each node, applies plugin apply methods, and constructs the task dependency DAG.
3. Execution : Determines task order based on dependencies, executes tasks (including parallel execution) to improve build efficiency.
Hook points are available throughout the lifecycle, allowing custom logic injection at various stages.
Build Tasks and Artifacts : The HAP build produces a release package containing resources , modules.abc , module.json , resources.index , and pack.info files.
Developing Custom Tasks : Edit hvigorfile.ts and register tasks via HvigorNode :
// 获取当前hvigorNode节点对象
const node = getNode(__filename);
// 注册Task
node.registerTask({
name: 'TaskName',
run() {
// implement custom operation
}
});
// 执行Task
hvigorw TaskNameDeveloping Custom Plugins : Define a plugin implementing the HvigorPlugin interface, apply it in the export declaration, and run with hvigorw --sync :
function customPlugin(): HvigorPlugin {
return {
pluginId: 'customPlugin',
apply(node: HvigorNode) {
console.log('hello customPlugin!');
}
};
}
export default {
system: appTasks,
plugins: [customPlugin()]
};
// Execute
hvigorw --syncRouting Plugin Development involves creating a custom decorator, parsing the TypeScript AST to extract routing metadata, and generating builder files, router map files, and index files. Key steps include:
Define the JRRouter decorator and its parameter interface.
Initialize the development environment (Node.js 16‑18, TypeScript, npm configuration).
Set up a TypeScript project, install dependencies, and configure .npmrc and package.json .
Implement utility functions for file scanning, builder generation, and router map creation.
Initialize plugin configuration based on the Hvigor node.
Export the plugin via routerPlugin function.
Example of the routing plugin’s core functions:
function getAllFiles(directoryPath: string): string[] {
return readdirSync(directoryPath).reduce((files, file) => {
const filePath = join(directoryPath, file);
const isDirectory = statSync(filePath).isDirectory();
return isDirectory ? [...files, ...getAllFiles(filePath)] : [...files, filePath];
}, []);
}
function createBuilderFile(templateModel: TemplateModel, config: RouterPluginConfig) {
const builderFilePath = join(config.generatedDir, ROUTER_BUILDER_NAME);
if (existsSync(builderFilePath)) {
unlinkSync(builderFilePath);
}
// ... generate file content and write
writeFileSync(builderFilePath, output, { encoding: "utf8" });
}
function routerPlugin(pluginConfig?: RouterPluginConfig): HvigorPlugin {
return {
pluginId: PLUGIN_ID,
apply(node: HvigorNode) {
executePlugin(initializeConfig(node, pluginConfig));
}
};
}The JREtsAnalyze class parses source files using the TypeScript compiler API, extracts annotations, and records page information for routing.
export class JREtsAnalyze {
analyzeResult: JRAnalyzeResult = new JRAnalyzeResult();
sourcePath: string;
constructor(filePath: string) { this.sourcePath = filePath; }
analyze() {
const sourceCode = readFileSync(this.sourcePath, "utf-8");
const sourceFile = ts.createSourceFile(this.sourcePath, sourceCode, ts.ScriptTarget.ES2021, false);
ts.forEachChild(sourceFile, node => {
try { this.parseNode(node); } catch (e) { console.error('Error while parsing node: ', e); }
});
}
// ...additional parsing methods
}Finally, export the plugin for use in a project:
export { routerPlugin } from './src/JRouterPlugin';In summary, the article provides a comprehensive guide to using Hvigor in HarmonyOS development, covering task and plugin creation, lifecycle management, routing plugin implementation, and practical code examples.
JD Tech Talk
Official JD Tech public account delivering best practices and technology innovation.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.