Skip to content

jairoblatt/light-script

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Todo:

  • defineScript
  • defineAsynScript
  • destroyScript
  • Vue 2 and Nuxt.js/3 plugin.
  • useScript and useAsynScript Vue 3/Nuxt 3 composable.
  • useScript React hook.
  • Unit tests.
  • SSR and SSG.
  • Improve docs.

📦 installation

npm:

npm i @jrblatt/light-script

yarn:

yarn add @jrblatt/light-script

🦜 Usage

ESM

import { defineScript } from '@jrblatt/light-script'

defineScript('https://my-script.js');

Cdn

You can use lightScript directly from a CDN via a script tag:

<script src="https://unpkg.com/@jrblatt/light-script@latest/dist/lightScript.min.js"></script>

<script>
const { defineScript } = lightScript;

defineScript('https://my-script.js');
</script>

Cdn + module

<script type="module">
 import { defineScript } from 'https://unpkg.com/@jrblatt/light-script@latest/dist/lightScript.min.js'

defineScript('https://my-script.js')
</script>

Cdn + module as importmap

<script type="importmap">
 {
    "imports": {
      "light-script": "https://unpkg.com/@jrblatt/light-script@latest/dist/lightScript.min.js"
    }
  }
</script>
<script type="module">
 import { defineScript } from '@jrblatt/light-script'

 defineScript('https://my-script.js');
<script>

Suspense mode

Some times you need to run async logic using the good old promises, in this case you can use the suspense: true option, wich will make defineScript return a plain promise function called suspense.

Using suspense option

Example

const { suspense } = defineScript('http://my-script.js', { suspense: true });

try {
 const success = await suspense();
 console.log(success);
} catch(error){
  console.error('Something went wrong!', error)
}

Type

function suspense(): Promise<LighScriptEvent>

Using defineAsyncScript

You can also load an async script without define the suspense: true option, instead use the sugar function defineAsyncScript.

Which in some cases helps to reduce verbosity :)

Example

 try {
    await defineAsyncScript('my-script.js');
 } catch(event) {
    console.error('Something went wrong!', event)
 }

defineAsyncScript is a sugar function to:

function defineAsyncScript(src, options){
    return defineScript(src, { suspense: true, ...options }).suspense()
}

Type

function defineAsyncScript(src: string, options: Omit<DefineScriptOptions, 'suspense'>): Promise<LighScriptEvent>

Note: onSuccess, onError and onSettled still called even if you are using suspense or defineAsynScript.

Example

then and onSuccess will be fired.

defineAsyncScript('my-script.js', { onSuccess: console.log }).then(console.log)

Remove a script

If you need to remove any lightScript of the Document flow, use destroyScript to do that.

Example

import { destroyScript }  from '@jrblatt/light-script';
// It will remove the eascript of the document.
destroyScript('my-script.js')

Type

function destroyScript(src: string): void;

Event payload

The event payload is emitted as then, catch, onSuccess, onError and onSettled are fired.

Example

defineScript('https://unpkg.com/vue@3/dist/vue.global.js', {
  onSuccess({ isCache, attempts, event }){
    if(!isCache){
        Vue.createApp({
          data: () => ({
              message: 'Hello Vue!'
          })
        }).mount('#app')
    }
  }
})

Type

{
 
  event: Event,  // onerror, onabort or onload event native payload.
  attempts: number // Attempts until the script is loaded or the retries ended.
  isCache: boolean, // If you try to load an already loaded script, then it will be true.
}

Example

import { defineScript } from '@jrblatt/light-script';

const { destroy, suspense } = defineScript('https://cdn.jsdelivr.net/npm/preact/dist/preact.min.js', {
  async: true,
  defer: true,
  id: 'preact',
  integrity: 'hash',
  module: true,
  referrerPolicy: 'strict-origin-when-cross-origin',
  retry: 4,
  retryDelay: 2000,
  wrapper: 'body',
  suspense: true,
  onError(e) {
    console.error(e);
  },
  onSettle(e) {
    console.warn(e);
  },
  onSuccess(e) {
    console.log(e)
  },
  onRetry(attempts) {
    console.warn(attempts)
  }
});

await suspense();

Options

Name type Default description
id String undefined Default script element attribute Id
async Boolean false Default script element attribute async
defer Boolean false Default script element attribute defer
integrity String undefined Default script element attribute integrity
module Boolean false Set this to true to define type="module"
noModule Boolean false Default script element attribute noModule
referrerPolicy String 'strict-origin-when-cross-origin' Default script element attribute referrerPolicy
retry Numberish 3 The failed script will retry until the failed script count meets that number.
retryDelay Numberish 1000 Set the time in ms between each retry.
wrapper Element - String document.head Specify target container. Can either be a selector or an actual element.
suspense Boolean false If set to true will return a suspense promise. Example
onSuccess Function undefined This function will fire any time the script successfully loaded.
onError Function undefined This function will fire if the script failed to load or is aborted.
onSettled Function undefined This function will fire any time the script is either successful or failure.
onRetry Function undefined This function will fire before any time the a new retry is performed.

📄 License

MIT License © 2022-PRESENT Jairo Blatt

About

🪶 A light way to load client-side scripts

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published