liquid-assets
v1.0.0
Published
A library for dealing with assets without requiring any build tools.
Downloads
1
Readme
Liquid Assets
A library for dealing with assets without requiring any build tools.
Overview
This library comprises of three things:
- A class to represent assets
- A class to generate URLs for assets (and find an asset given a URL)
- 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
Classes
Functions
Typedefs
liquid-assets
Liquid Assets
- liquid-assets
- .Asset
- new exports.Asset(options)
- .size ⇒ number
- .type ⇒ string
- .name ⇒ string
- .ext ⇒ string
- .Symbol.asyncIterator()
- .toString() ⇒ string
- .FileAsset
- .InlineAsset
- .asset ⇒ FileAsset
- .Asset
liquid-assets.Asset
A generic representation of an asset
Kind: static class of liquid-assets
- .Asset
- new exports.Asset(options)
- .size ⇒ number
- .type ⇒ string
- .name ⇒ string
- .ext ⇒ string
- .Symbol.asyncIterator()
- .toString() ⇒ string
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
- new exports.Asset(options)
- .size ⇒ number
- .type ⇒ string
- .name ⇒ string
- .ext ⇒ string
- .Symbol.asyncIterator()
- .toString() ⇒ string
- .FileAsset
- .InlineAsset
- .asset ⇒ FileAsset
- .Asset
liquid-assets.Asset
A generic representation of an asset
Kind: static class of liquid-assets
- .Asset
- new exports.Asset(options)
- .size ⇒ number
- .type ⇒ string
- .name ⇒ string
- .ext ⇒ string
- .Symbol.asyncIterator()
- .toString() ⇒ string
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 |