본문으로 건너뛰기

Plugin Development

Plugin Overview

tokript 는 js 혹은 ts 를 cli 로 실행시키는 모듈입니다. node 환경의 어떤 스크립트도 tokript plugin 이 될 수 있습니다.

tokript 는 그럼 단순 스크립트 모음인가요? npm script 과 다른게 없지 않나요? 네 맞습니다. 하지만 npm script 와 다르게, 다양한 option 값들을 config, cli option 에 쉽게 넘겨 사용 할 수 있게끔 합니다.

즉 하나의 cli 모듈을 쉽게 만들게 함으로써, 스크립트를 공유하고 재 사용하기 더 좋은 환경을 만드는데 의의가 있습니다.

해당문서는 tokript plugin 개발에 대한 내용을 다룹니다.

Installation

npm i -D @toktokhan-dev/cli

A Simple example

간단한 플러그인 예제를 통해 플러그인 개발 방법을 알아봅니다. 문서를 모두 읽기 힘들다면 해당 내용만으로 플러그인을 충분히 개발 가능합니다.

Define Plugin

my-plugin.ts
import fs from "fs";
import path from "path";

import { defineCommand } from "@toktokhan-dev/cli";

/**
* 플러그인의 config 타입을 정의합니다.
*
* - tok-cli.config.ts 에서 해당 플러그인의 option 을 정의할 때 사용됩니다.
* - config 파일은 js, ts 이기 때문에, 옵션 객체의 각 property 는 함수, 배열 등 어떤 타입이든 정의 가능합니다.
* - run 함수의 인자 type 으로 사용됩니다.
*/
export type GenTxtConfig = {
output: string;
};

export const genTxt = defineCommand<"gen:txt", GenTxtConfig>({
/**
* 플러그인의 이름을 정의합니다.
*
* - tokript {command} 로 실행됩니다.
* - tok-cli.config 에서 옵션 정의시 해당 옵션의 key 값으로 사용됩니다.
*/
name: "gen:txt",
/**
* 플러그인의 설명을 정의합니다.
*
* - tokript help 실행시 표기됩니다.
*/
description: "텍스트 파일을 생성합니다.",
/**
* 플러그인 실행시 사용할 config 의 기본값을 정의합니다.
*
* - 특정 옵션이 `--output` 과 같은 `cli option` 이나 `tok-cli.config.ts` 에 정의 되지 않았을 때 사용됩니다.
*/
default: {
output: path.resolve("generated", "my.txt"),
},
/**
* --output, -o 와 같은 cli option 을 정의합니다.
*
* - cli option 에 정의되지 않은 옵션은 오직 config 파일에서만 정의 가능합니다.
* - cli option 은 원시값, 원시값 배열과 같은 간단한 값만 사용 가능합니다. ex) string, string[]
* - tokript help {command} 시 정의한 alias, 설명, 기본값을 확인할 수 있습니다.
*/
cliOptions: [
{
name: "output",
alias: "o",
description: "텍스트 파일 생성 경로",
type: "string",
},
],
/**
* 플러그인 실행 함수를 정의합니다.
*
* - config: GenTxtConfig 타입의 config 객체가 인자로 넘어옵니다.
* - config 객체는 default, cli option, tok-cli.config.ts 에 정의된 값들이 합쳐진 값입니다.
* - config 우선순위는 cli option > tok-cli.config.ts > default 입니다.
* - run 함수는 플러그인의 실제 동작을 정의합니다.
*/
run: (config) => {
fs.writeFileSync(config.output, "hello world");
},
});

Register Plugin

tok-cli.config.ts
import { genTxt } from "./my-plugin";

/**
* config 를 정의합니다.
*
* RootConfig 의 제네릭에 plugin 의 type 을 정의 함으로써 type safe 하게 option 을 정의할 수 있습니다.
*/
const config: RootConfig<{ plugins: [typeof genTxt] }> = {
/**
* tokript 가 해당 플러그인을 실행시키기 위해 조회하는 플러그인 리스트입니다.
*/
plugins: [genTxt],
/**
* 정의된 이름을 key 값으로 config type 을 value 로써 config 정의가 가능합니다.
*/
"gen:txt": {
output: "custom/path/my.txt",
},
};

export default config;

Run Plugin

generated/my.txt 파일이 생성됩니다.

npx tokript gen:txt

script 에 option 을 넘겨 사용 가능합니다.

npx tokript gen:txt --output 'generated/hello.txt'

option alias 로 사용 가능합니다.

npx tokript gen:txt -o 'generated/hello.txt'

help 커멘드로 기입해둔 설명과 사용방법을 조회 가능합니다.

npx tokript help gen:txt
output: npx tokript help gen:txt
 _             _             _           _
| |_ ___ | | __ _ __ (_) _ __ | |_
| __| / _ \ | |/ / | '__| | | | '_ \ | __|
| |_ | (_) | | < | | | | | |_) | | |_
\__| \___/ |_|\_\ |_| |_| | .__/ \__|
|_|
Usage: tokript gen:txt [options]

텍스트 파일을 생성합니다.

Options:
-o, --output <string> 텍스트 파일 생성 경로 (default: "generated/my.txt")
-h, --help display help for command

Configuration

플러그인 실행시, 유저의 인풋으로 정의되는 설정값입니다. 함수로 치면 인자에 해당하는 부분입니다.

tokript 는 1 개의 config 타입과 총 3 종류의 config 가 존재합니다.
Default Config, File Config, Cli Option 는 합쳐저서, 단 하나의 타입을 가진 하나의 config 객체로써, defineCommandrun 함수의 인자로 넘어옵니다.

각 config 의 우선순위는 Cli Option > File Config > Default Config 순 입니다.

Config Type

플러그인 실행시 사용될 단하나의 config 타입을 정의합니다.
이후에 소개할 Default Config, File Config, Cli Option 은 해당 타입에서 벗어날 수 없습니다.

Config Type 은 단 하나의 객체로 정의가 가능하며, property 는 함수, 배열 등 어떤 타입이든 정의 가능합니다.

defineCommand 의 2번째 제네릭의 config type 을 정의할 수 있습니다.

my-plugin.ts
export type GenTxtConfig = {
output: string;
};

export const genTxt = defineCommand<"gen:txt", GenTxtConfig>({
name: "gen:txt",
run: (config) => {
fs.writeFileSync(config.output, "hello world");
},
});

Default Config

defineCommenddefault property 를 통해 플러그인 실행시 사용할 config 의 기본값을 정의할 수 있습니다.
모든 옵션은 선택적으로 기본값 정의가 가능합니다.

default config 에 정의된 값은 특정 옵션이 --output 과 같은 cli option 이나 tok-cli.config.ts 에 정의 되지 않았을 때 사용됩니다.
즉, 별다른 유저 인풋이 존재하지 않을때 사용됩니다.

my-plugin.ts
export const genTxt = defineCommand<'gen:txt', GenTxtConfig>({
...
default: {
output: path.resolve('generated', 'my.txt'),
onSuccess: () => console.log('success')
},
})

File Config

tok-cli.config.ts 에서 해당 플러그인의 config 를 정의할 수 있습니다.

  • RootConfig (type): @toktokhan-dev/cli 에서 제공하는 config type 입니다. 플러그인의 함수 타입들을 제너릭으로 넘겨주면 더 type safe 하게 config 를 정의할 수 있습니다.
  • config.plugins: RootConfig 의 plugins property 에 플러그인을 등록 할 수 있습니다.
  • config.[commandName]: RootConfig 의 plugins property 에 등록된 플러그인의 이름을 key 값으로 해당 플러그인의 option 을 정의할 수 있습니다.

Default Config 보다 우선순위가 높기때문에, Default Config 에 정의된 값은 File Config 에 정의된 값으로 대체됩니다.

tok-cli.config.ts
import { RootConfig } from "@toktokhan-dev/cli";
import { genTxt } from "./my-plugin";

const config: RootConfig<{
plugins: [typeof genTxt];
}> = {
plugins: [genTxt],
"gen:text": {
output: "custom/path/my.txt",
},
};

Cli Option

defineCommandcliOptions property 를 통해 --output, -o 와 같은 cli option 을 정의할 수 있습니다.

  • cliOption[index].name: cli option 의 이름을 정의합니다.
  • cliOption[index].type: cli option 의 타입을 정의합니다. 원시값, 원시값 배열과 같은 간단한 값만 사용 가능합니다. ex) string, string[]
  • cliOption[index].alias(optional): cli option 의 alias 를 정의합니다.
  • cliOption[index].description(optional): cli option 의 설명을 정의합니다.

cli name 과 type 은 필수값이며, config type 에서 벗어날 수 없습니다.
config 중 특정 옵션을 선택적으로 설정할 수 있으며, cli 로 넘겨주는 옵션이기 때문에, string, string[] 와 같은 원시값, 원시값 배열만 사용 가능합니다.

my-plugin.ts

export const genTxt = defineCommand<'gen:txt', GenTxtConfig>({
...
cliOptions: [
{
name: 'output',
type: 'string',
alias: 'o',
description: '텍스트 파일 생성 경로',
},
],
})

terminal 에서 실행시 --output, -o 처럼, cli option 을 사용할 수 있습니다. 가장 우선순위가 높기때문에, File Config, Default Config 에 정의된 값은 cli option 에서 넘겨준 값으로 대체됩니다.

tokript gen:txt --output 'generated/hello.txt'

tokript help ${command} 커멘드로 기입해둔 설명과 사용방법을 조회 가능합니다.

tokript help gen:txt

Config Priority

각 config 의 우선순위는 Cli Option > File Config > Default Config 순 입니다.
간단한 예제로 확인해봅니다.

example 1

Cli OptionFile Config 에 아무런 값도 정의되지 않았으므로 output 은 default 값인 generated/my.txt 로 설정됩니다.

// my-plugin.ts
defineCommand({
cliOptions: [
{
name: 'output',
type: 'string',
},
],
default: {
output: 'default/path/my.txt'
},
})

// tok-cli.config.ts
{
"gen:text": {}
}

tokript gen:txt

example 1

File Config 에 output 값이 정의되었고, cli option 으로는 아무런 값도 넘겨지지 않았으므로, output 은 file config 값인 custom/path/my.txt 로 설정됩니다.

// my-plugin.ts
defineCommand({
cliOptions: [
{
name: 'output',
type: 'string',
},
],
default: {
output: 'default/path/my.txt'
},
})

// tok-cli.config.ts
{
"gen:text": {
output: 'custom/path/my.txt'
}
}

tokript gen:txt

example 3

Cli Option 은 가장 순위가 높으므로 output 은 cli option 으로 넘겨준 값인 generated/hello.txt 로 설정됩니다.

// my-plugin.ts
defineCommand({
cliOptions: [
{
name: 'output',
type: 'string',
},
],
default: {
output: 'default/path/my.txt'
},
})

// tok-cli.config.ts
{
"gen:text": {
output: 'custom/path/my.txt'
}
}
tokript gen:txt --output 'generated/hello.txt'