@talend/assets-api
Version:
A set of API designed to access assets using CDN
75 lines (54 loc) • 3.64 kB
Markdown
# /assets-api
Assets are files from a npm package which can be needed at some point by a web application. It can be a stylesheet, a SVG icon, a js script, a json file, etc...
At Talend our web applications may rely on a CDN to load libraries like lodash, d3 but also /design-system using UMD distribution format. An application rely on a CDN depending of the execution context; We are following 12 factors principals. So the same code base must work in both case so an asset url may change from `/cdn/my-package/1.2.3/dist/my-assets.svg` to `https://mycdn.talend.com/my-package/1.2.3/dist/my-assets.svg`.
This is made possible using custom configuration of `/dynamic-cdn-webpack-plugin`. Now we also need to be able to load translations, icons and more **assets** from the code.
This package exposes a simple and friendly API to let developers access assets without the complexity of computing URL depending on the context (CDN or not).
## Learn with examples
First you need to ensure you have setup the [babel plugin](https://npmjs.com/package/@talend/babel-plugin-assets-api) or you use @talend/scripts-core to build your lib / project.
Then we can start with this global example:
```javascript
import assetsAPI from '/assets-api';
// The lowest level API is the ability to get the URL of anything. Here, a CSS file.
const href = assetsApi.getURL('/dist/styles/ag-grid.css', 'ag-grid-community');
// babel will add all missing arguments and at runtime you will have
console.log(href);
// -> 'https://unpkg.com/ag-grid-community@25.0.0/dist/styles/ag-grid.css';
// Higher level APIs enable users to get a JSON file for locales, timezones, etc...
async function getTopology(file) {
const locales = await assetsAPI.getJSON(
`/dist/assets/maps/${file}.topo.json`,
);
}
// We can also lazy load a component from a UMD.
// This one is a bit more complex. You have to know that React.lazy wants a default esModule from a Promise. This is what getUMD + toDefaultModule give you.
const AgGridReact = React.lazy(() =>
assetsApi
.getUMD('ag-grid-community')
.then(() => assetsApi.getUMD('ag-grid-react'))
.then(mod => assetsApi.toDefaultModule(mod.AgGridReact))
);
// Finally, this is how we load styles from a lazy loaded component.
export default function DataGrid(props) {
//...
useEffect(() => {
const href = assetsApi.getURL('/dist/styles/ag-grid.css', 'ag-grid-community');
assetsApi.addStyle({ href });
}, []);
//...
return <React.Suspense fallback={}>AgGridReact</React.Suspense>
}
```
## Requirements
- devs do not have to write the version: it is injected at build time thanks to [babel plugin](https://npmjs.com/package/@talend/babel-plugin-assets-api)
- the assets' version is implicitly specified by the consumer webapp (`talend-scripts` adds global data that is then read by the API at runtime)
- the inject.js script will be able to control this version (it should update meta value)
- `sessionStorage` is used to let anyone override a version locally
- the API is compatible with `React.Suspense` / lazy React APIs
- for UMDs, the path is computed form `module-to-cdn` and injected at build time thanks to the babel plugin
- for relative paths in a package, the name of the package is optional
## How to configure the CDN to use ?
The assets API uses a global function to compute the URL: `window.Talend.getCDNUrl()`. By default the package will add it for you. This version will use a global `CDN_URL` with the following shape:
```javascript
`${CDN_URL}/${info.name}/${info.version}${info.path}`;
```
but fallbacks to unpkg.com public CDN if no CDN_URL is provided.