Skip to main content

Generating a Package

tip

If you don't want to use the structure of the package template or you find it too complex, the Generating a Package in Its Simplest Form page provides a simpler way to create a package with just two files.

Now that we can create manifests for our application in a reusable way, let's package our library so that others can use it in their own projects.

Instead of modifying the existing application project, we will create a new package project. It will have the necessary structure and files to be published as a package.

To create a package project, run the following command:

anemos new example-package --language typescript --project-type package

Structure of the package project is a bit different from the application project. The main difference is that the package project is designed to be reusable and shareable, while the application project is meant to be used for generating output files for a specific use case.

Package projects also have slightly different values in the package.json and tsconfig.json (if you use TypeScript) files to match the package project structure. We will not go into details about these files as the changes are minimal.

Library Code (lib directory)

The lib directory contains the code that will be shared with the package. It consists of the necessary classes and functions to generate the output files. It will also contain the public API definition for the package.

The files under the lib directory are very similar to the ones that we had created in the application project. The main difference in manifest generation is that the package project template creates a pod instead of a deployment and a service. The index file, on the other hand, serves a different purpose, so it will be structured differently.

Index file in the lib directory acts as the public API for the package. It exports the Options class and an add function that takes a Builder and Options, creates a new Component using the given options and adds it to the given Builder. The Component class will not be exported, as it is not part of the public API and is only used internally by the package.

lib/index.ts
import * as anemos from "@ohayocorp/anemos";
import { Component } from "./component";
import { Options } from "./options";

export { Options };

export function add(builder: anemos.Builder, options?: Options): anemos.Component {
const component = new Component(options);
builder.addComponent(component);

return component;
}

Test Code (test directory)

Package project template includes a test directory that contains the code to generate output files with the package. The test cases act like small applications that use the package to generate output files, allowing us to verify its behavior.

Inside the test directory, you will find the index file that serves as the entry point for the test cases. It imports all the test cases and runs them one by one.

test/index.ts
import * as anemos from "@ohayocorp/anemos";

function runTest(testDirectory: string): void {
// Change the current working directory to the test directory
// so that the test outputs are written to the correct location.
process.env.ANEMOS_OUTPUT_PATH=`${anemos.file.currentScriptDirectory()}/output/${testDirectory}`;
require(testDirectory);
}

// Run basic tests.
runTest(`./test/basic`);

Each test case is defined as a separate module inside its own directory. Anemos creates a simple test case under the basic directory.

test/basic/index.ts
import * as anemos from "@ohayocorp/anemos";
import * as app from "../../lib";

const builder = new anemos.Builder("1.31", anemos.KubernetesDistribution.Minikube, anemos.EnvironmentType.Development);

app.add(builder, {
name: "test-example-package",
namespace: "test-namespace",
image: "test-image:v1",
});

builder.build();

Contents of the test/basic/index.ts file is be similar to the index.ts file in the application project. The only notable difference is the require statements at the top of the file. Instead of importing the Component and Options classes from the component.ts and options.ts files, the package's public API is imported from the lib directory.

When you run the build command, it will compile the TypeScript files in the lib directory and generate the corresponding JavaScript files in the dist directory. The test/index.ts file will also be compiled and executed. The output files will be generated in the dist/test/output/basic directory. You can check them to verify that the package works as expected.

Publishing the Package

Run the following command to directly publish the package to the official NPM registry:

anemos package publish

You can also use the following command to build the package as a tarball file, which you can then publish manually or share with others:

anemos package pack

This command requires you to have an NPM account and be logged in. If you haven't done this yet, you can create an account on the NPM website and log in using the command:

anemos package login
tip

If you want to publish the package to a private registry, you can use the --registry option with the anemos package publish command. For example:

anemos package login --registry https://my-private-registry.com
anemos package publish --registry https://my-private-registry.com