Generating a Package
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:
- TypeScript
- JavaScript
anemos new example-package --language typescript --project-type package
anemos new example-package --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.
- TypeScript
- JavaScript
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;
}
const anemos = require("@ohayocorp/anemos");
const Component = require("./component");
const Options = require("./options");
/**
* @param {anemos.Builder} builder
* @param {Options} options
* @returns {anemos.Component}
*/
function add(builder, options) {
const component = new Component(options);
builder.addComponent(component);
return component;
}
module.exports = {
add,
Options
};
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.
- TypeScript
- JavaScript
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`);
const anemos = require("@ohayocorp/anemos");
function runTest(testDirectory) {
// Set the base output path to the test case directory so that
// the output files are created in the correct place.
process.env.ANEMOS_OUTPUT_PATH=`${anemos.file.currentScriptDirectory()}/${testDirectory}/output`;
require(testDirectory);
}
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.
- TypeScript
- JavaScript
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.
const anemos = require("@ohayocorp/anemos");
const app = require("../../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.js
file is similar to the index.js
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.js
and options.js
files, the package's public
API is imported from the lib
directory.
When you run the build command, the tests that are defined inside the test/index.js
will be executed.
The output files will be generated in the test/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
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