Build utilities for Now (Vercel) serverless platform runtime development
npx @tessl/cli install tessl/npm-now--build-utils@1.3.0@now/build-utils provides essential build utilities and abstractions for developing runtimes on the Now (later Vercel) serverless platform. It offers a comprehensive API for handling file operations, Lambda function creation and management, build process orchestration, and framework detection.
npm install @now/build-utilsimport {
FileBlob,
FileFsRef,
FileRef,
Lambda,
createLambda,
getLambdaOptionsFromFunction,
Prerender,
download,
DownloadedFiles,
glob,
GlobOptions,
rename,
getWriteableDirectory,
readConfigFile,
streamToBuffer,
isSymbolicLink,
execAsync,
spawnAsync,
execCommand,
spawnCommand,
runNpmInstall,
runBundleInstall,
runPipInstall,
runPackageJsonScript,
runShellScript,
installDependencies,
getNodeVersion,
getLatestNodeVersion,
getDiscontinuedNodeVersions,
getSpawnOptions,
detectBuilders,
detectFramework,
detectRoutes,
detectOutputDirectory,
detectApiDirectory,
detectApiExtensions,
DetectorFilesystem,
shouldServe,
debug,
NowBuildError
} from "@now/build-utils";For CommonJS:
const {
FileBlob,
FileFsRef,
FileRef,
Lambda,
createLambda,
getLambdaOptionsFromFunction,
Prerender,
download,
DownloadedFiles,
glob,
GlobOptions,
rename,
getWriteableDirectory,
readConfigFile,
streamToBuffer,
isSymbolicLink,
execAsync,
spawnAsync,
execCommand,
spawnCommand,
runNpmInstall,
runBundleInstall,
runPipInstall,
runPackageJsonScript,
runShellScript,
installDependencies,
getNodeVersion,
getLatestNodeVersion,
getDiscontinuedNodeVersions,
getSpawnOptions,
detectBuilders,
detectFramework,
detectRoutes,
detectOutputDirectory,
detectApiDirectory,
detectApiExtensions,
DetectorFilesystem,
shouldServe,
debug,
NowBuildError
} = require("@now/build-utils");import {
FileFsRef,
createLambda,
download,
execAsync
} from "@now/build-utils";
// Create file references
const entrypoint = new FileFsRef({ fsPath: "/path/to/index.js" });
// Download and process files
const files = {
"index.js": entrypoint,
"package.json": new FileFsRef({ fsPath: "/path/to/package.json" })
};
const downloadedFiles = await download(files, "/tmp/work");
// Execute build commands
await execAsync("npm", ["install"], { cwd: "/tmp/work" });
// Create Lambda function
const lambda = await createLambda({
files: downloadedFiles,
handler: "index.handler",
runtime: "nodejs14.x"
});@now/build-utils is built around several key components:
FileRef, FileFsRef, FileBlob) representing different file storage typesCore file handling utilities for managing different types of file references and performing filesystem operations during builds.
function download(files: Files, basePath: string, meta?: Meta): Promise<DownloadedFiles>;
function glob(pattern: string, options?: GlobOptions): Promise<string[]>;
function rename(files: Files, renameFn: (name: string) => string): Files;Utilities for creating and managing serverless Lambda functions, including bundling files into deployment packages.
function createLambda(options: CreateLambdaOptions): Promise<Lambda>;
function getLambdaOptionsFromFunction(options: GetLambdaOptionsFromFunctionOptions): Promise<Pick<LambdaOptions, 'memory' | 'maxDuration'>>;
interface CreateLambdaOptions {
files: Files;
handler: string;
runtime: string;
memory?: number;
maxDuration?: number;
environment?: { [key: string]: string };
}Tools for executing build scripts, package manager commands, and shell operations with proper environment setup.
function execAsync(command: string, args: string[], opts?: SpawnOptions): Promise<{ stdout: string; stderr: string; code: number }>;
function spawnAsync(command: string, args: string[], opts?: SpawnOptions): Promise<void>;
function runNpmInstall(destPath: string, args?: string[], spawnOpts?: SpawnOptions, meta?: Meta): Promise<void>;Automatic detection of project frameworks and appropriate builders for zero-configuration deployments.
function detectBuilders(files: string[], pkg?: PackageJson, options?: Options): { builders: Builder[]; errors: ErrorResponse[]; warnings: WarningResponse[] };
function detectFramework(options: DetectFrameworkOptions): Promise<string | null>;
function detectRoutes(filePaths: string[], builders: Builder[], options?: DetectRoutesOptions): Route[];Three specialized file classes for representing different types of file storage and enabling seamless file operations.
class FileRef implements File {
constructor(options: FileRefOptions);
toStream(): NodeJS.ReadableStream;
}
class FileFsRef implements File {
constructor(options: FileFsRefOptions);
static fromFsPath(options: FileFsRefOptions): Promise<FileFsRef>;
toStream(): NodeJS.ReadableStream;
}
class FileBlob implements File {
constructor(options: FileBlobOptions);
static fromStream(options: FromStreamOptions): Promise<FileBlob>;
toStream(): NodeJS.ReadableStream;
}Static site generation and prerendering support with Lambda fallbacks for dynamic routes.
class Prerender {
constructor(options: PrerenderOptions);
}
interface PrerenderOptions {
expiration: number;
lambda: Lambda;
fallback: FileBlob | FileFsRef | FileRef | null;
group?: number;
}Additional utility functions for build processes and request handling.
function shouldServe(options: ShouldServeOptions): boolean;
function debug(message: string, ...additional: any[]): void;
interface ShouldServeOptions {
requestPath: string;
entrypoint: string;
files: { [path: string]: FileFsRef };
workPath: string;
config: Config;
}interface File {
type: string;
mode: number;
contentType?: string;
toStream(): NodeJS.ReadableStream;
fsPath?: string;
}
interface Files {
[filePath: string]: File;
}
interface Config {
[key: string]: string | string[] | boolean | number | { [key: string]: string } | BuilderFunctions | undefined;
maxLambdaSize?: string;
includeFiles?: string | string[];
excludeFiles?: string | string[];
bundle?: boolean;
ldsflags?: string;
helpers?: boolean;
rust?: string;
debug?: boolean;
zeroConfig?: boolean;
import?: { [key: string]: string };
functions?: BuilderFunctions;
outputDirectory?: string;
buildCommand?: string;
devCommand?: string;
framework?: string;
nodeVersion?: string;
}
interface Meta {
isDev?: boolean;
skipDownload?: boolean;
requestPath?: string;
filesChanged?: string[];
filesRemoved?: string[];
env?: Env;
buildEnv?: Env;
}
interface BuildOptions {
files: Files;
entrypoint: string;
workPath: string;
config: Config;
meta?: Meta;
}
interface Env {
[name: string]: string | undefined;
}
interface BuilderFunctions {
[key: string]: {
memory?: number;
maxDuration?: number;
runtime?: string;
includeFiles?: string;
excludeFiles?: string;
};
}
interface NodeVersion {
major: number;
range: string;
runtime: string;
discontinueDate?: Date;
}
interface Builder {
use: string;
src: string;
config?: Config;
}
class NowBuildError extends Error {
public hideStackTrace: boolean;
public code: string;
public link?: string;
constructor(options: { message: string; code: string; link?: string });
}
interface AnalyzeOptions {
/** All source files of the project */
files: { [filePath: string]: FileRef };
/** Name of entrypoint file for this particular build job */
entrypoint: string;
/** A writable temporary directory where you are encouraged to perform your build process */
workPath: string;
/** An arbitrary object passed by the user in the build definition */
config: Config;
}
interface PrepareCacheOptions {
/** All source files of the project */
files: Files;
/** Name of entrypoint file for this particular build job */
entrypoint: string;
/** A writable temporary directory where you are encouraged to perform your build process */
workPath: string;
/** A writable temporary directory where you can build a cache to use for the next run */
cachePath: string;
/** An arbitrary object passed by the user in the build definition */
config: Config;
}
interface NowRewrite {
source: string;
destination: string;
}
interface NowRedirect {
source: string;
destination: string;
statusCode?: number;
}
interface NowHeader {
source: string;
headers: NowHeaderKeyValue[];
}
interface NowHeaderKeyValue {
key: string;
value: string;
}
// JSON Schema definitions for validation
const functionsSchema: {
type: 'object';
minProperties: 1;
maxProperties: 50;
additionalProperties: false;
patternProperties: {
'^.{1,256}$': {
type: 'object';
additionalProperties: false;
properties: {
runtime?: { type: 'string'; maxLength: 256 };
memory?: { enum: number[] };
maxDuration?: { type: 'number'; minimum: 1; maximum: 900 };
includeFiles?: { type: 'string'; maxLength: 256 };
excludeFiles?: { type: 'string'; maxLength: 256 };
};
};
};
};
const buildsSchema: {
type: 'array';
minItems: 0;
maxItems: 128;
items: {
type: 'object';
additionalProperties: false;
required: ['use'];
properties: {
src?: { type: 'string'; minLength: 1; maxLength: 4096 };
use: { type: 'string'; minLength: 3; maxLength: 256 };
config?: { type: 'object' };
};
};
};