0.9.3 • Published 7 months ago

kubik v0.9.3

Weekly downloads
1
License
ISC
Repository
github
Last release
7 months ago

Kubik

⚠️ Warning: Kubik is currently in pre-1.0.0 release. Expect potential changes and experimental features that may not be fully stable yet.

Kubik is a simple task runner for node.js with first-class TypeScript support.

Kubik tasks are defined by TypeScript / Node.js scripts, with dependencies to other tasks. Kubik supports running tasks with different parallelization modes and has a built-in watch mode.

Quick Start

Any build.(m)js script can be converted to a task by importing Task and running Task.init in the very beginning of the script:

import { Task } from 'kubik';

Task.init(import.meta);

/* ... build script ...  */

The Task.init method accepts configuration (dependencies & watch mode configuration), see API section.

Use the following commands to run tasks:

  • Build: npx kubik ./build.mjs
  • Watch mode: npx kubik -w ./build.mjs
  • Debug (run without Kubik): node build.mjs or tsx build.mjs
  • Run sequential build: npx kubik -j 1 ./build.mjs

A real-life example is available here.

Task dependencies

Kubik allows defining dependencies between tasks using deps option in the Task.init method:

// build-main.mjs
import { Task } from 'kubik';

Task.init(import.meta, {
  deps: ['./other-task.mjs'], // these are relative to script folder
});

// ... run some tasks

To run tasks with their dependencies to completion, run:

npx kubik ./build-main.mjs

Multiple roots

In a complicated projects, it might be necessary to build a project from multiple entry points. In this case, you can pass multiple entry points to Kubik:

npx kubik ./build-main.mjs ./build-other.mjs

In this case, if both build-main.mjs and build-other.mjs depend on shared.mjs task, then the task will be executed only once.

Running services

By default, task is considered successful if its process completes with 0 exit code, and unsuccessful if it fails with non-zero code.

However, certain tasks require a running process; for example, launching development server. In this case, you can use Task.done() to notify Kubik that the task completed and it's dependants can start executing:

import { Task } from 'kubik';

Task.init(import.meta);

// ...launch HTTP server... 
// Report the task as complete.
Task.done();

TypeScript support

Kubik supports running tasks defined in a .ts / .mts files using tsx. To use typescript, simply install tsx along side with kubik, and use .ts/.tsx extension to write your scripts:

  1. Install tsx:

    npm i --save-dev tsx
  2. Write your scripts in a .ts or .mts files:

    // hello.ts
    
    import { Task } from 'kubik';
    
    Task.init(import.meta);
    const foo: String = 'Hello, typescript!';
    console.log(foo);
  3. Run your tasks as usual:

    npx kubik ./hello.ts

Watch Mode

Kubik supports watch mode where it listens for changes on the file system and reruns tasks and their dependencies.

To run watch mode, use -w or --watch flag:

npx kubik -w ./build.mjs

In watch mode, Kubik launches a terminal app that shows progress, duration and logs from all the tasks:

There are a few shortcuts available to navigate inside the watch mode app:

  • To cycle focus through panels, use Tab and Shift-Tab
  • To scroll logs of the focused pane, use arrows, j, k, Ctrl-U, Ctrl-D, gg and Shift-G.
  • You can also use mouse to scroll logs

By default, Kubik watches for changes in files commonly involved in build tasks, such as:

  • package.json
  • package-lock.json
  • tsconfig.json

However, you can customize files and directories to watch and to ignore during Task initialization:

import { Task } from 'kubik';

Task.init(import.meta, {
  deps: ['./build-third-party.mjs'],
  watch: ['./src'],  // these are relative to script folder
  ignore: ['./src/generated'],  // these are relative to script folder too
});

NOTE: Be careful with watch mode: if the build procedure changes some of the watched files, then Kubik will re-run the build one time, causing "infinite" builds. You'll observe this with tasks never completing. Use ignore option to mitigate this behavior.

Parallelization

Kubik supports -j, --jobs <number> flag to customize number of parallel jobs. By default, Kubik allows an unlimited number of parallel jobs.

Environment Files

Kubik supports -e, --env-file <env file> flag to load environment variables from a file.

npx kubik -e .env ./build.mjs

This will load all the environment variables from .env file, and pass them to all scripts.

Shebang

You can use kubik shebang in scripts, like this:

#!/usr/bin/env npx kubik

import { Task } from 'kubik';

Task.init(import.meta, {
  watch: ['./src'],
  ignore: ['./src/generated'],
});

API

The Task.init function prepares the build environment, offering utilities like $ for shell commands (powered by execa), __dirname, and __filename based on the current script's context.

The whole API boils down to the following:

#!/usr/bin/env npx kubik

import { Task } from 'kubik';
import fs from 'fs';

const {
  $, // execa shell runner, that uses __dirname as CWD
  __dirname, // **this** script directory absolute path
  __filename, // **this** script file absolute path
} = Task.init(import.meta, {
  name: 'my library',
  watch: ['./src'], // all the paths are resolved relative to this script
  ignore: ['./src/generated'], // relative to this script
  deps: ['../third-party/build.mjs'], // relative to this script
});

console.log(Task.isWatchMode()); // wether the script is being run under watch mode.

// Use $ to run commands, e.g. typescript.
// Note that $ uses __dirname as CWD.
await $`tsc --pretty -p .`;

// If node.js process does not exit (i.e. it runs a server),
// then we can notify Kubik explicitly that the task is done.
Task.done(); 

Debugging

You can run build scripts as regular node.js scripts; in this case, these are executed directly by node.js, with no Kubik in the way.

node ./build-main.mjs
0.9.3

7 months ago

0.1.0

10 months ago

0.3.0

10 months ago

0.2.0

10 months ago

0.9.0

10 months ago

0.8.1

10 months ago

0.8.0

10 months ago

0.7.1

10 months ago

0.9.2

10 months ago

0.9.1

10 months ago

0.5.0

10 months ago

0.4.0

10 months ago

0.7.0

10 months ago

0.6.0

10 months ago

0.5.1

10 months ago

0.0.3

8 years ago

0.0.2

9 years ago

0.0.1

9 years ago