resource-injector
v1.5.0
Published
The ResourceInjector class dynamically loads JavaScript and CSS into the webpage, ensuring each resource is loaded only once, with error handling and optional load timeouts.
Downloads
9
Maintainers
Readme
0.7kB gzipped
Install
$ yarn add resource-injector
# or
$ npm i resource-injectorImport
import ResourceInjector from 'resource-injector';Quick Start
const injector = new ResourceInjector();
// 1. Load a JavaScript file into <head> (automatically deferred)
await injector.loadResource({
url: 'https://cdn.example.com/analytics.js',
type: 'script',
injectTo: 'head', // <‑‑ new!
});
// 2. Load a CSS file
await injector.loadResource({
url: 'https://cdn.example.com/theme.css',
type: 'style',
appendTimestamp: true, // <‑‑ bust browser cache when needed
});API
injector.loadResource(config): Promise<void>
| Option (required bold) | Type | Default | Description |
|:----------------------------------|:---------------------------------------------------------|:------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| url | string | — | Absolute or relative path to the resource. |
| type | 'script' \| 'style' | — | Resource kind. |
| options | Partial<HTMLScriptElement> \| Partial<HTMLLinkElement> | {} | Any valid attributes for the underlying element e.g. async, defer, id, type="module" … |
| timeout | number | 10000 | Milliseconds to wait before the Promise rejects. |
| forceReload | boolean | false | Remove the existing element (if any) and fetch again. |
| appendTimestamp | boolean | false | Adds ?t={Date.now()} to the network URL for easy cache‑busting.For internal caching the original URL (without query) is still used, so repeated calls with different timestamps are treated as one resource. |
| injectTo script‑only | 'head' \| 'body' | 'body' | Where to insert the <script> tag.'head' starts download earlier; 'body' preserves historical behaviour. |
| container | HTMLElement | undefined | Explicit parent element; overrides injectTo. |
Automatic
defer
WheninjectTo: 'head'and you did not supplyasync/defer, the injector setsdefer=trueso scripts do not block parsing and execute after DOMContentLoaded.
Return value
Promise<void> – resolved on load, rejected on error or timeout.
Examples
Cache‑bust & reload
await injector.loadResource({
url: '/build/app.js',
type: 'script',
appendTimestamp: true,
forceReload: true,
});Inject into a custom container
const shadowRoot = document.getElementById('widget')!.shadowRoot!;
await injector.loadResource({
url: 'https://cdn.example.com/widget.js',
type: 'script',
container: shadowRoot, // overrides injectTo
});Parallel loading
await Promise.all([
injector.loadResource({ url: '/a.js', type: 'script' }),
injector.loadResource({ url: '/b.css', type: 'style' }),
]);
console.log('Everything ready');Advanced behaviour
- Single‑flight cache – Internally a
Mapstores Promises keyed by the base URL (query string stripped).
Two calls for the same file will share one network request. - Timeout Guard – Individual
loadResourcecalls can specify their own timeout (defaults to10 s). - Force Reload – Set
forceReloadtotrueto delete any previously injected node and restart download.
License
MIT
