liquid-assets

1.0.0 • Public • Published

Liquid Assets

A library for dealing with assets without requiring any build tools.

Overview

This library comprises of three things:

  1. A class to represent assets
  2. A class to generate URLs for assets (and find an asset given a URL)
  3. A function to serve assets over Node's http server

The following example shows all of these parts in use:

import { asset, AssetMap, assetRequestHandler } from 'liquid-assets';

// Reference an asset relative to this file (1)
const profilePic = asset('./profile.jpg', import.meta.url);

// Keep a bidirectional map of Asset objects and URLS (2)
const mapper = await AssetMap.register('http://example.com/assets/', [profilePic]);

// Create a function that serves the assets (3)
const serveAsset = assetRequestHandler(mapper);

export default async function requestHandler(req, res) {
    // Serve any registered assets
    if(await serveAsset(req, res)) {
        // An asset was found and served; exit the request handler
        return;
    }

    // No asset was found; serve the default route
    return `<html><body>
        <h1>Mr Example</h1>
        <p>Hello, my name is Mr. Example. Here's a picture of me:</p>
        <img src="${
            // Get the URL for the asset from the asset map
            await mapper.getUrl(profilePic);
        }">`

}

Usage patterns

I've tried to make this library simple enough to use in whatever configuration is needed:

Webpack-style

If you're used to doing import assetUrl from './asset.jpg';, you might find the following pattern useful:

First, set up your mapper in its own file:

import { AssetMap, Asset, assetRequestHandler } from 'liquid-assets';

export const mapper = new AssetMap('http://example.com/assets/');

// Make sure you use this in your server callback so the assets are actually served
export const serveAssets = assetRequestHandler(mapper);

export default (...args) => mapper.getUrl(new Asset(...args));

Then, whenever you need to reference an asset in another file, import the asset mapper and use it to generate a URL:

import urlFor from './asset-mapper.js';

const virus = await urlFor('./virus.exe', import.meta.url);

export default `<a href="${virus}">Click here</a> for a picture of a cute panda!`;

Template-first

If you want to be able to specify assets in your templates without having to have a mapper set up first, that's possible too using a library like encode-html-template-tag that can replace assets at render time:

import { asset } from 'liquid-assets';
import html from 'encode-html-template-tag';

export const vom = asset('./vom.ogg', import.meta.url);

export default html`
This is what my cat sounds like when she's about to throw up:
<audio src="${vom}"></audio>`;

Then, in your server code, you can replace the asset with its URL at render time:

import html from 'encode-html-template-tag';
import { AssetMap, assetRequestHandler, Asset } from 'liquid-assets';
import vomTemplate, { vom } from './cat-vomit.js';

const notFound = html`That page was not found`;

export default async function(origin = 'http://example.com') {
    const assets = await AssetMap.register(`${origin}/assets/`, [vom]);
    const assetServer = assetRequestHandler(assets);

    return async function(req, res) {
        if(await assetServer(req, res)) {
            return;
        }

        // Imagine this is your router function
        const template = req.url === '/' ? vomTemplate : notFound;

        // Render the output and replace Assets with their URLs
        const output = await template.render(value => {
            if(value instanceof Asset) {
                // Get the asset URL
                const url = await assets.getUrl(value);

                // We can also make the URL relative if we want
                return url.toString().replace(origin, '');
            }

            return value;
        });
    }
}

Dependencies

  • mime-types: ^2.1.33

Modules

liquid-assets

Liquid Assets

liquid-assets

Liquid Assets

Classes

AssetMap

Generates URLs for assets, and maintains a map of those URLs to their asset objects.

Functions

assetRequestHandler(assetMapper)function

Create a request handler for serving assets. Note that the request handler expects asset URLs to be content-addressed, and therefore sets the cache-control header to immutable. If you don't want this behaviour, don't use this function.

Typedefs

AssetMapOptions : object

Options for constructing the AssetMap

RequestHandlerBoolean

Asset request handler

liquid-assets

Liquid Assets

liquid-assets.Asset

A generic representation of an asset

Kind: static class of liquid-assets

new exports.Asset(options)

Create a new asset

Param Type Description
options Object Options
options.type string The mime-type of the asset
options.toStream function A function that returns an async iterable yeilding the asset's contents
options.toString function A function that returns the asset represented as a data url
options.name string An optional filename for the asset
options.size number The asset size in bytes

asset.size ⇒ number

Get the asset's file size in bytes

Kind: instance property of Asset

asset.type ⇒ string

Get the asset's mime type

Kind: instance property of Asset

asset.name ⇒ string

Kind: instance property of Asset
Returns: string - The filename of the asset

asset.ext ⇒ string

Kind: instance property of Asset
Returns: string - The extname of the asset

asset.Symbol.asyncIterator()

Generator that yields the asset's contents

Kind: instance method of Asset

asset.toString() ⇒ string

Kind: instance method of Asset
Returns: string - Data URL of the asset

liquid-assets.FileAsset

An asset on the filesystem

Kind: static class of liquid-assets

new exports.FileAsset(file, baseUrl)

Create a new FileAsset

Param Type Description
file string Absolute or relative path of the file
baseUrl string The base file:// URL to calculate relative path from

liquid-assets.InlineAsset

An asset declared in code, stored in application memory

Kind: static class of liquid-assets

new exports.InlineAsset(blob, type, name)

Create a new InlineAsset

Param Type Description
blob Buffer | string The contents of the asset
type string The mimetype of the asset
name string Optional filename for the asset

liquid-assets.asset ⇒ FileAsset

Create a new FileAsset

Kind: static constant of liquid-assets

Param Type Description
file string Absolute or relative path of the file
baseUrl string The base file:// URL to calculate relative path from

liquid-assets

Liquid Assets

liquid-assets.Asset

A generic representation of an asset

Kind: static class of liquid-assets

new exports.Asset(options)

Create a new asset

Param Type Description
options Object Options
options.type string The mime-type of the asset
options.toStream function A function that returns an async iterable yeilding the asset's contents
options.toString function A function that returns the asset represented as a data url
options.name string An optional filename for the asset
options.size number The asset size in bytes

asset.size ⇒ number

Get the asset's file size in bytes

Kind: instance property of Asset

asset.type ⇒ string

Get the asset's mime type

Kind: instance property of Asset

asset.name ⇒ string

Kind: instance property of Asset
Returns: string - The filename of the asset

asset.ext ⇒ string

Kind: instance property of Asset
Returns: string - The extname of the asset

asset.Symbol.asyncIterator()

Generator that yields the asset's contents

Kind: instance method of Asset

asset.toString() ⇒ string

Kind: instance method of Asset
Returns: string - Data URL of the asset

liquid-assets.FileAsset

An asset on the filesystem

Kind: static class of liquid-assets

new exports.FileAsset(file, baseUrl)

Create a new FileAsset

Param Type Description
file string Absolute or relative path of the file
baseUrl string The base file:// URL to calculate relative path from

liquid-assets.InlineAsset

An asset declared in code, stored in application memory

Kind: static class of liquid-assets

new exports.InlineAsset(blob, type, name)

Create a new InlineAsset

Param Type Description
blob Buffer | string The contents of the asset
type string The mimetype of the asset
name string Optional filename for the asset

liquid-assets.asset ⇒ FileAsset

Create a new FileAsset

Kind: static constant of liquid-assets

Param Type Description
file string Absolute or relative path of the file
baseUrl string The base file:// URL to calculate relative path from

assetRequestHandler(assetMapper) ⇒ function

Create a request handler for serving assets. Note that the request handler expects asset URLs to be content-addressed, and therefore sets the cache-control header to immutable. If you don't want this behaviour, don't use this function.

Kind: global function
Returns: function - Request handling function

Param Type Description
assetMapper AssetMapper The asset mapper containing the assets to serve

AssetMapOptions : object

Options for constructing the AssetMap

Kind: global typedef
Properties

Name Type Description
options.algorithm string The algorithm to use when generating the filename hash; default sha1
options.length number How many characters in length the hash part of the URL should be; default 7
options.minSize number The minimum size the asset needs to be for an http URL to be generated. Anything below this size will be converted as a data: URL

RequestHandler ⇒ Boolean

Asset request handler

Kind: global typedef
Returns: Boolean - True if an asset was sent, false if no matching asset was found

Param Type Description
req IncomingMessage The Node incoming request object
res OutgoingResponse The Node HTTP response object

Package Sidebar

Install

npm i liquid-assets

Weekly Downloads

2

Version

1.0.0

License

ISC

Unpacked Size

28.1 kB

Total Files

9

Last publish

Collaborators

  • paulkiddle