@fab/static
TypeScript icon, indicating that this package has built-in type declarations

0.1.8 • Public • Published

name: "@fab/static" route: "/packages/fab-static" menu: Packages

💎 @fab/static

Builds a FAB from a directory of static HTML and assets, with an optional server-side component.

oclif  Version  Downloads/week  License 

Getting Started

Install @fab/static as a development dependency:

yarn add --dev @fab/static
npm install --dev @fab/static

Add a couple of scripts to your package.json:

  "scripts": {
    "build": "[your existing build step]",
+   "build:fab": "npm run build && npm run fab:compile",
+   "fab:compile": "fab-static [dirname]"
  },
}

Replace dirname with wherever your built files live (build for Create React App & friends, public for Gatsby, dist for some others)

We've added two scripts here, fab:compile which runs the fab-static builder, and build:fab that builds the project first. Most of the time, and especially you're using a FAB-enabled platform like linc.sh, you'll mostly run build:fab, but having a separate fab:compile step can be handy as you set things up.

You can test it out by running:

npm run build:fab

Once this is complete, you should have a fab.zip file (and a .fab directory with a bunch of build files). Those don't need to be checked in to your repository, so you can add them to your .gitignore file with this one-liner:

echo "\n.fab\nfab.zip" >> .gitignore

If you want to spin up your fab.zip file locally, you can use @fab/serve. You can either install it globally:

yarn global add @fab/serve
npm install --global @fab/serve

fab-serve fab.zip

Or use the awesome npx (which is bundled with NodeJS) to run a command-line NPM package without needing to install it:

npx @fab/serve fab.zip

You should see your app running on http://localhost:3000!

Note: this process will add one file fab.zip and one directory .fab into your project.

Usage

@fab/static takes the following options:

USAGE
  $ fab-static [DIRECTORY]

OPTIONS
  -h, --help                         show CLI help
  -o, --output=output                Output FAB file (default fab.zip)
  -p, --prod-settings=prod-settings  Path to production settings json
  -s, --server=server                Path to server entry file or directory
  -w, --working-dir=working-dir      Intermediate directory for working (default .fab)
  --intermediate-only

EXAMPLE
  $ fab-static ~/src/my-project/build

Efficiently handling assets

The fab.zip file only allows two components—the first is a server.js, which is auto-generated by @fab/static, and the second is an _assets directory. If your assets aren't in an _assets subdirectory (e.g. a public or static directory instead), @fab/static will automatically move them and generate server-side code to wire things up at runtime. This process works fine, but it's inefficient.

To read more about the rewriting process, visit the @fab/compile documentation, or for a more general overview of why _assets is a core part of the FAB spec, visit https://fab.dev/kb/no-assets-dir

Environment Variables

The FAB format has first-class support for environment variables which you can read about here: https://fab.dev/kb/environment-variables.

To specify production environment variables to be bundled into the FAB itself, add a production-settings.json file in the same directory as your package.json file and it will be automatically included into the build. You can also specify a path with -p or --prod-settings if you'd prefer to keep your settings file elsewhere/name it differently.

A production settings file might look like:

{
  "API_URL": "https://api.example.com",
  "CLIENT_ID": "1cd5e6a4871f98616a38abb2eada56868ca5aad2"
}

These values are for the production environment (read why). To supply non-production variables that will be injected in place of these settings, consult the documentation of your hosting platform e.g. Linc

Accessing Environment Variables at Runtime

@fab/static dynamically injects a <script> tag into any HTML response as it's being streamed to the client:

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- FAB SETTINGS SCRIPT TAG INJECTED HERE -->
    <meta charset="UTF-8" />
    <title>Document</title>
    <!-- ... -->
  </head>
  <body>
    <!-- ... -->
  </body>
</html>

That <script> tag has the following format:

<script type="text/javascript">
  window.FAB_SETTINGS = {
    "API_URL": "https://staging.api.example.com"
  }
</script>

Whatever the settings object passed to render (which will be a combination of production settings as well as any environment-specific overrides), @fab/static will serialise them to JSON and inject them as window.FAB_SETTINGS. This code will execute before any other, meaning you can always rely on FAB_SETTINGS to be available by the time your app is booted.

fetch(`${window.FAB_SETTINGS.API_URL}/endpoint`).then(
  // ...
)

To use the same environment variables during development, it's recommended to add a layer of abstraction between FAB_SETTINGS (available once the FAB is built) and process.env (available during development). For example

// src/config.js

const lookupEnvVar = name => {
  // Use FAB_SETTINGS if defined
  if (typeof FAB_SETTINGS === 'object') {
    return FAB_SETTINGS[name]
    
  // Otherwise use process.env
  } else {
    // Note: some build systems (like Create React App) only expose
    // process.env vars that start with a prefix (like REACT_APP_)
    return process.env[`REACT_APP_${name}`]
  }
}

export default {
  API_URL: lookupEnvVar('API_URL'),
  API_KEY: lookupEnvVar('API_KEY'),
  // ...
}

You can use the config throughout your app like so:

import config from '../config'

fetch(`${config.API_URL}/endpoint`).then(
  // ...
)

Adding a server

Despite the name, @fab/static is capable of running virtually any server-side logic you'd like. From use-cases like rewriting or forwarding URLs, proxying APIs, or simply providing a health check, you can supercharge your FAB by using the -s or --server flag to fab-static.

For simple use-cases, you can use a single file:

fab-static --server path/to/server.js

For more complex setups, you can specify a whole directory which will be bundled into the FAB:

fab-static --server path/to/server

In this example, the path/to/server/index.js will be used as the entry point, but the whole directory will be copied into the FAB.

Server API

Your server.js or server/index.js file can export one of three endpoints:

export async function modifyRequest(settings, request) {
  // default behaviour is nothing, needs no return value
}

export async function route(settings, path, request) {
  // must return something, by default returns the path unchanged
  return path
}

export async function modifyResponse(settings, response) {
  // default behaviour is nothing, needs no return value
}

Readme

Keywords

Package Sidebar

Install

npm i @fab/static

Weekly Downloads

1

Version

0.1.8

License

MIT

Unpacked Size

25.6 kB

Total Files

14

Last publish

Collaborators

  • evanderkoogh
  • geelen