All Projects → microsoft → Backfill

microsoft / Backfill

Licence: mit
A JavaScript caching library for reducing build time

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects

Projects that are alternatives of or similar to Backfill

netlify-plugin-cache
⚡ Generic plugin for caching any files and/or folders between Netlify builds
Stars: ✭ 19 (-62%)
Mutual labels:  build, cache
Buildbuddy
BuildBuddy is an open source Bazel build event viewer, result store, and remote cache.
Stars: ✭ 182 (+264%)
Mutual labels:  build, cache
Sst Elements
SST Architectural Simulation Components and Libraries
Stars: ✭ 36 (-28%)
Mutual labels:  cache
Cache
A promise-aware caching API for Amp.
Stars: ✭ 46 (-8%)
Mutual labels:  cache
Graphql Factory
A toolkit for building GraphQL
Stars: ✭ 44 (-12%)
Mutual labels:  build
Use Axios Request
Data fetching is easy with React Hooks for axios!
Stars: ✭ 38 (-24%)
Mutual labels:  cache
Wheel
关于net nio os cache db rpc json web http udp tcp mq 等多个小工具的自定义实现
Stars: ✭ 45 (-10%)
Mutual labels:  cache
Htmlcache
Laravel middleware to cache the rendered html
Stars: ✭ 35 (-30%)
Mutual labels:  cache
Cachelper
Stars: ✭ 48 (-4%)
Mutual labels:  cache
Rxnetwork
A swift network library based on Moya/RxSwift.
Stars: ✭ 43 (-14%)
Mutual labels:  cache
Openjdk8 Releases
AdoptOpenJDK main binary releases for OpenJDK 8 with HotSpot
Stars: ✭ 46 (-8%)
Mutual labels:  build
Synchrotron
Caching layer load balancer.
Stars: ✭ 42 (-16%)
Mutual labels:  cache
Spring Boot
spring-boot 项目实践总结
Stars: ✭ 989 (+1878%)
Mutual labels:  cache
Lfscache
LFS Cache is a caching Git LFS proxy.
Stars: ✭ 45 (-10%)
Mutual labels:  cache
Exchange Rates
💱 Querying a rate-limited currency exchange API using Redis as a cache
Stars: ✭ 37 (-26%)
Mutual labels:  cache
Pomodoro
A simple WordPress translation cache
Stars: ✭ 47 (-6%)
Mutual labels:  cache
Golang Docker Build Tutorial
A template project to create a minimal Docker image for a Go application
Stars: ✭ 36 (-28%)
Mutual labels:  build
Grabver
Gradle Automatic Build Versioning Plugin - An easy Gradle plugin that follows semver.org rules to automatically generate the Patch version, Build number and Code version, while Major, Minor and Pre-Release suffix remain under our control.
Stars: ✭ 39 (-22%)
Mutual labels:  build
Extended image
A powerful official extension library of image, which support placeholder(loading)/ failed state, cache network, zoom pan image, photo view, slide out page, editor(crop,rotate,flip), paint custom etc.
Stars: ✭ 1,021 (+1942%)
Mutual labels:  cache
Easycaching
💥 EasyCaching is an open source caching library that contains basic usages and some advanced usages of caching which can help us to handle caching more easier!
Stars: ✭ 1,047 (+1994%)
Mutual labels:  cache

backfill

A JavaScript caching library for reducing build time.

🔌 Easy to install: Simply wrap your build commands inside backfill -- [command]
☁️ Remote cache: Store your cache on Azure Blob or as an npm package
⚙️ Fully configurable: Smart defaults with cross-package and per-package configuration and environment variable overrides

backfill is under active development and should probably not be used in production, yet. We will initially focus on stability improvements. We will look into various optimization strategies, adding more customization, and introducing an API for only running scripts in packages that have changed and skipping others altogether.

Current prerequisites:

  • git (for running --audit)
  • yarn.lock and yarn workspaces (for optimized hashing)

These prerequisites can easily be loosened to make backfill work with npm, Rush, and Lerna.

Why

When you're working in a multi-package repo you don't want to re-build packages that haven't changed. By wrapping your build scripts inside backfill you enable storing and fetching of build output to and from a local or remote cache.

Backfill is based on two concepts:

  1. Hashing: It will hash the files of a package, its dependencies and the build command
  2. Caching: Using the hash key, it will look for build output from a local or remote cache. If there's a match, it will backfill the package using the cache. Otherwise, it will run the build command and persist the output to the cache.

Install

Install backfill using yarn:

$ yarn add --dev backfill

Usage - CLI

backfill -- [command]

Typically you would wrap your npm scripts inside backfill, like this:

{
  "name": "package",
  "scripts": {
    "build": "backfill -- tsc -b"
  }
}

--audit

Backfill can only bring back build output from the folders it was asked to cache. A package that modifies or adds files outside of the cached folder will not be brought back to the same state as when it was initially built. To help you debug this you can add --audit to your backfill command. It will listen to all file changes in your repo (it assumes you're in a git repo) while running the build command and then report on any files that got changed outside of the cache folder.

Configuration

Backfill will look for backfill.config.js in the package it was called from and among parent folders recursively and then combine those configs together.

To configure backfill, simply export a config object with the properties you wish to override:

module.exports = {
  cacheStorageConfig: {
    provider: "azure-blob",
    options: { ... }
  }
};

The default configuration object is:

{
  cacheStorageConfig: { provider: "local" },
  clearOutputFolder: false,
  internalCacheFolder: "node_modules/.cache/backfill",
  logFolder: "node_modules/.cache/backfill",
  logLevel: "info",
  mode: "READ_WRITE",
  name: "[name-of-package]",
  outputGlob: ["lib/**"],
  packageRoot: "path/to/package",
  producePerformanceLogs: false,
  validateOutput: false
}

The outputGlob is a list of globs describing the files you want to cache. outputGlob should be expressed as a relative path from the root of each package. If you want to cache package-a/lib, for instance, you'd write outputGlob: ["lib/**"]. If you also want to cache the pacakge-a/dist/bundles folder, you'd write outputGlob: ["lib/**", "dist/bundles/**"].

The configuration type is:

export type Config = {
  cacheStorageConfig: CacheStorageConfig;
  clearOutputFolder: boolean;
  internalCacheFolder: string;
  logFolder: string;
  logLevel: LogLevels;
  mode: "READ_ONLY" | "WRITE_ONLY" | "READ_WRITE" | "PASS";
  name: string;
  outputGlob: string[];
  packageRoot: string;
  performanceReportName?: string;
  producePerformanceLogs: boolean;
  validateOutput: boolean;
};

Environment variable

You can override configuration with environment variables. Backfill will also look for a .env-file in the root of your repository, and load those into the environment. This can be useful when you don't want to commit keys and secrets to your remote cache, or if you want to commit a read-only cache access key in the repo and override with a write and read access key in the PR build, for instance.

See getEnvConfig() in ./packages/config/src/envConfig.ts.

Set up remote cache

Microsoft Azure Blob Storage

To cache to a Microsoft Azure Blob Storage you need to provide a connection string and the container name. If you are configuring via backfill.config.js, you can use the following syntax:

module.exports = {
  cacheStorageConfig: {
    provider: "azure-blob",
    options: {
      connectionString: "...",
      container: "..."
      maxSize: 12345
    }
  }
};

Options

connectionString
retrieve this from the Azure Portal interface
container
the name of the blob storage container
maxSize (optional)
max size of a single package cache, in the number of bytes

You can also configure Microsoft Azure Blob Storage using environment variables.

BACKFILL_CACHE_PROVIDER="azure-blob"
BACKFILL_CACHE_PROVIDER_OPTIONS='{"connectionString":"...","container":"..."}'

Npm package

To cache to an NPM package you need to provide a package name and the registry URL of your package feed. This feed should probably be private. If you are configuring via backfill.config.js, you can use the following syntax:

module.exports = {
  cacheStorageConfig: {
    provider: "npm",
    options: {
      npmPackageName: "...",
      registryUrl: "..."
    }
  }
};

You can also provide a path to the .npmrc user config file, to provide auth details related to your package feed using the npmrcUserconfig field in options.

You can also configure NPM package cache using environment variables.

BACKFILL_CACHE_PROVIDER="npm"
BACKFILL_CACHE_PROVIDER_OPTIONS='{"npmPackageName":"...","registryUrl":"..."}'

Skipping cache locally

Sometimes in a local build environment, it is useful to compare hashes to determine whether to execute the task without having to explicitly use a separate directory for the cache.

One caveat, this is using output that the task produced and one could possibly modify the output on a local development environment. For this reason, this is an opt-in behavior rather than the default.

The main benefit of using this strategy is a significant speed boost. Backfill can skip file copying of the cached outputs if it can rely on the built artifacts. Hashing is CPU-bound while caching is I/O-bound. Using this strategy results in speed gains but at the cost of needing to trust the outputs have not be altered by the user. While this usually is true, it is prudent to also provide a command in your repository to clean the output along with the saved hashes.

You can configure this from the backfill.config.js file this way:

module.exports = {
  cacheStorageConfig: {
    provider: "local-skip"
  }
};

Like other cases, you can also use the environment variable to choose this storage strategy:

BACKFILL_CACHE_PROVIDER="local-skip"

API

Backfill provides an API, this allows for more complex scenarios, and performance optimizations.

const backfill = require("backfill/lib/api");

const packagePath = getPath(packageName);

const logger = backfill.makeLogger("verbose", process.stdout, process.stderr);
const packagehash = await backfill.computeHash(packagePath, logger);

const fetchSuccess = await backfill.fetch(packagePath, packageHash, logger);

if (!fetchSuccess) {
  await runBuildCommand();
  await backfill.put(packagePath, packageHash, logger);
}


Performance Logs

You can optionally output performance logs to disk. If turned on, backfill will output a log file after each run with performance metrics. Each log file is formatted as a JSON file. You can turn performance logging by setting producePerformanceLogs: true in backfill.config.js.

Contributing

Ways to contribute

This project welcomes contributions and suggestions.

Describing your changes

When submitting source code changes, be sure to accompany the changes with a change file. Change files can be generated with the yarn change command.

Contributor License Agreement (CLA)

Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].