@rnx-kit/golang
v0.2.3
Published
Integrate Go into your monorepo and create native apps that accelerate development and CI builds
Downloads
23
Keywords
Readme
@rnx-kit/golang
Integrate Go into your monorepo and create native apps that accelerate development and CI builds.
Motivation
JavaScript monorepos make extensive use of NodeJs-based tools like TypeScript, Babel, Metro and Webpack, to name just a few. As monorepos grow in size and complexity, developers are finding that the tools don't scale well. Native applications like esbuild and swc are emerging to address poor toolchain performance, and more are expected to appear in the coming years.
Developers need to optimize the tools they use to keep engineering productivity high. Turning the crank on a PR should take minutes, not hours. Converting pieces of the toolchain to native code is required to achieve this goal.
Usage
There are three core functions in this library. To build and use Go programs, you'll need to integrate them into your task runner and CI loops.
type Logger = {
info: (message: string) => void;
warn: (message: string) => void;
error: (message: string) => void;
};
// Task factories for installing Go, and building/running Go programs.
function goInstallTask(logger?: Logger): () => Promise<void>;
function goBuildTask(logger?: Logger): () => Promise<void>;
function goTask(
logger: Logger | undefined,
name: string,
...args: string[]
): () => Promise<void>;
Go installation first looks for an existing version of Go in the system path. If nothing was found, a local distribution of Go is downloaded and cached in the monorepo. Future "install" calls will detect the local installation, skipping this entire step.
The Go build task looks for Go apps under ./go/{project-name}
and stores built
binaries under ./bin. Each app is built using the command "go build -o
{bin-path}
". The Go app's binary name doesn't need to match {project-name}
.
The Go execution task looks for the named binary in ./bin and executes it with an optional set of arguments.
Pre-requisites
Windows 10 in a minimum requirement. This package uses tar
which ships with
that version of Windows.
Build Tasks
The three functions are task factories. They each return a function that you can run as a build step in systems like Just or Gulp.
import { task, logger } from "just-scripts";
import { goBuildTask, goTask } from "@rnx-kit/golang";
// Make new Just tasks to install Go and build Go programs
task("go:install", goInstallTask(logger));
task("go:build", goBuildTask(logger));
task("go", series("go:install", "go:build"));
// Tie them into the mainline build task
task("build", build("clean", "go", "lint", "ts"));
// Add a Just task wrapper to execute the Go app named "transcode-media"
// which reformats video files into 640x480 @ 30 fps using a well-known
// encoding like AVC/H.264.
//
// This can be executed as part of other tasks, or directly on the
// command-line: npm run just-scripts transcode-media.
//
task(
"transcode-media",
goTask(logger, "transcoder", assetsDir, transcoderOutputDir)
);
CI Loop Tasks
Some CI systems like GitHub Actions have VM images that come with Go preinstalled. To use the installed copy in GitHub Actions, you may need to add a step like setup-go to your CI pipeline definition:
- uses: actions/setup-go@v2
with:
go-version: "^1.14.0"
If you're using a different CI provider, find out if Go is on the build VMs. It will save you time and bandwidth on each CI run.
.gitignore
Avoid checking in Go apps, as they are platform-specific and take up a lot of
room. Add an entry to .gitignore
to exclude the bin directory from each
package:
+/packages/*/bin/
/packages/*/dist/
/packages/*/lib/
node_modules/
clean
build task
It's a good idea to clean out each package's bin
directory when running a
clean
build task. This removes any stale Go apps, which will be rebuilt as
needed.
import { cleanTask } from "just-scripts";
export const clean = cleanTask({
paths: [
+ "bin",
"lib",
].map((p) => path.join(process.cwd(), p)),
});