From 7dfc5aa6ceab7f6c7eeb8da18290f3ba796767a8 Mon Sep 17 00:00:00 2001 From: harlan Date: Thu, 28 Mar 2024 01:53:41 +1100 Subject: [PATCH] feat: global script registration --- README.md | 17 +++++++++++++++++ playground/nuxt.config.ts | 3 +++ src/module.ts | 31 ++++++++++++++++++++++++++++--- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6479d583..3afdfacf 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,23 @@ addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] }) ## Guides +### Loading Scripts Globally + +If you prefer a config based approach, you can load scripts globally by defining them in your `nuxt.config.ts`. + +```ts +export default defineNuxtConfig({ + scripts: { + globals: [ + 'https://cdn.jsdelivr.net/npm/js-confetti@latest/dist/js-confetti.browser.js', + { + assetStrategy: 'bundle' + } + ] + } +}) +``` + ### Bundling Scripts Bundling scripts can allow you to serve them from your own server, improving privacy and performance. It diff --git a/playground/nuxt.config.ts b/playground/nuxt.config.ts index 44e7bac3..ad8e91bf 100644 --- a/playground/nuxt.config.ts +++ b/playground/nuxt.config.ts @@ -6,6 +6,9 @@ export default defineNuxtConfig({ ], devtools: { enabled: true }, scripts: { + globals: [ + 'https://cdn.jsdelivr.net/npm/vue@3.2.20/dist/vue.global.prod.js', + ], overrides: { 'cloudflare-turnstile': { assetStrategy: 'bundle', diff --git a/src/module.ts b/src/module.ts index e2455349..3b88189a 100644 --- a/src/module.ts +++ b/src/module.ts @@ -1,17 +1,21 @@ -import { addBuildPlugin, addImportsDir, createResolver, defineNuxtModule } from '@nuxt/kit' +import { addBuildPlugin, addImportsDir, addPlugin, addTemplate, createResolver, defineNuxtModule } from '@nuxt/kit' import { readPackageJSON } from 'pkg-types' -import type { NuxtUseScriptOptions } from './runtime/types' +import type { NuxtUseScriptInput, NuxtUseScriptOptions } from './runtime/types' import { setupDevToolsUI } from './devtools' import { NuxtScriptAssetBundlerTransformer } from './plugins/transform' import { setupPublicAssetStrategy } from './assets' import { logger } from './logger' export interface ModuleOptions { + /** + * Register scripts that should be loaded globally on all pages. + */ + globals?: (NuxtUseScriptInput | [NuxtUseScriptInput, NuxtUseScriptOptions])[] /** * Override the static script options for specific scripts based on their provided `key` or `src`. */ overrides?: { - [key: string]: Pick + [key: string]: Pick } /** Configure the way scripts assets are exposed */ assets?: { @@ -70,6 +74,27 @@ export default defineNuxtModule({ nuxt.options.runtimeConfig['nuxt-scripts'] = { version } addImportsDir(resolve('./runtime/composables')) + if (config.globals?.length) { + // create a virtual plugin + const template = addTemplate({ + filename: 'modules/nuxt-scripts/plugin.client.mjs', + getContents() { + return `import { defineNuxtPlugin, useScript } from '#imports' +export default defineNuxtPlugin({ + setup() { + ${config.globals?.map(g => typeof g === 'string' + ? ` useScript("${g}")` + : ` useScript(${JSON.stringify(g[0])}, ${JSON.stringify(g[1])} })`).join('\n')} + } +})` + }, + }) + addPlugin({ + src: template.dst, + mode: 'client', + }) + } + const scriptMap = new Map() const { normalizeScriptData } = setupPublicAssetStrategy(config.assets)