mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
feat(nuxt): prompt to install nuxt/scripts
on usage (#27010)
Co-authored-by: Harlan Wilton <harlan@harlanzw.com>
This commit is contained in:
parent
7e3b613421
commit
589b4037c1
102
packages/nuxt/src/app/composables/script-stubs.ts
Normal file
102
packages/nuxt/src/app/composables/script-stubs.ts
Normal file
@ -0,0 +1,102 @@
|
||||
import type { UseScriptInput } from '@unhead/vue'
|
||||
import { createError } from './error'
|
||||
|
||||
function renderStubMessage (name: string) {
|
||||
const message = `\`${name}\` is provided by @nuxt/scripts. Check your console to install it or run 'npx nuxi@latest module add @nuxt/scripts' to install it.`
|
||||
if (import.meta.client) {
|
||||
throw createError({
|
||||
fatal: true,
|
||||
statusCode: 500,
|
||||
statusMessage: message,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScript<T extends Record<string | symbol, any>> (input: UseScriptInput, options?: Record<string, unknown>) {
|
||||
renderStubMessage('useScript')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useElementScriptTrigger (...args: unknown[]) {
|
||||
renderStubMessage('useElementScriptTrigger')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useConsentScriptTrigger (...args: unknown[]) {
|
||||
renderStubMessage('useConsentScriptTrigger')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useAnalyticsPageEvent (...args: unknown[]) {
|
||||
renderStubMessage('useAnalyticsPageEvent')
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptGoogleAnalytics (...args: unknown[]) {
|
||||
renderStubMessage('useScriptGoogleAnalytics')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptPlausibleAnalytics (...args: unknown[]) {
|
||||
renderStubMessage('useScriptPlausibleAnalytics')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptCloudflareWebAnalytics (...args: unknown[]) {
|
||||
renderStubMessage('useScriptCloudflareWebAnalytics')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptFathomAnalytics (...args: unknown[]) {
|
||||
renderStubMessage('useScriptFathomAnalytics')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptMatomoAnalytics (...args: unknown[]) {
|
||||
renderStubMessage('useScriptMatomoAnalytics')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptGoogleTagManager (...args: unknown[]) {
|
||||
renderStubMessage('useScriptGoogleTagManager')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptSegment (...args: unknown[]) {
|
||||
renderStubMessage('useScriptSegment')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptFacebookPixel (...args: unknown[]) {
|
||||
renderStubMessage('useScriptFacebookPixel')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptXPixel (...args: unknown[]) {
|
||||
renderStubMessage('useScriptXPixel')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptIntercom (...args: unknown[]) {
|
||||
renderStubMessage('useScriptIntercom')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptHotjar (...args: unknown[]) {
|
||||
renderStubMessage('useScriptHotjar')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptStripe (...args: unknown[]) {
|
||||
renderStubMessage('useScriptStripe')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptLemonSqueezy (...args: unknown[]) {
|
||||
renderStubMessage('useScriptLemonSqueezy')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptVimeoPlayer (...args: unknown[]) {
|
||||
renderStubMessage('useScriptVimeoPlayer')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptYouTubeIframe (...args: unknown[]) {
|
||||
renderStubMessage('useScriptYouTubeIframe')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptGoogleMaps (...args: unknown[]) {
|
||||
renderStubMessage('useScriptGoogleMaps')
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function useScriptNpm (...args: unknown[]) {
|
||||
renderStubMessage('useScriptNpm')
|
||||
}
|
@ -20,6 +20,7 @@ import importsModule from '../imports/module'
|
||||
|
||||
import { distDir, pkgDir } from '../dirs'
|
||||
import { version } from '../../package.json'
|
||||
import { scriptsStubsPreset } from '../imports/presets'
|
||||
import { ImportProtectionPlugin, nuxtImportProtections } from './plugins/import-protection'
|
||||
import type { UnctxTransformPluginOptions } from './plugins/unctx'
|
||||
import { UnctxTransformPlugin } from './plugins/unctx'
|
||||
@ -125,6 +126,14 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
}
|
||||
})
|
||||
|
||||
// Prompt to install `@nuxt/scripts` if user has configured it
|
||||
// @ts-expect-error scripts types are not present as the module is not installed
|
||||
if (nuxt.options.scripts) {
|
||||
if (!nuxt.options._modules.some(m => m === '@nuxt/scripts' || m === '@nuxt/scripts-nightly')) {
|
||||
await import('../core/features').then(({ installNuxtModule }) => installNuxtModule('@nuxt/scripts'))
|
||||
}
|
||||
}
|
||||
|
||||
// Add plugin normalization plugin
|
||||
addBuildPlugin(RemovePluginMetadataPlugin(nuxt))
|
||||
|
||||
@ -550,6 +559,12 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!options._modules.some(m => m === '@nuxt/scripts' || m === '@nuxt/scripts-nightly')) {
|
||||
options.imports = defu(options.imports, {
|
||||
presets: [scriptsStubsPreset],
|
||||
})
|
||||
}
|
||||
|
||||
// Nuxt Webpack Builder is currently opt-in
|
||||
if (options.builder === '@nuxt/webpack-builder') {
|
||||
if (!await import('./features').then(r => r.ensurePackageInstalled('@nuxt/webpack-builder', {
|
||||
|
@ -111,6 +111,33 @@ const granularAppPresets: InlinePreset[] = [
|
||||
},
|
||||
]
|
||||
|
||||
export const scriptsStubsPreset = {
|
||||
imports: [
|
||||
'useConsentScriptTrigger',
|
||||
'useAnalyticsPageEvent',
|
||||
'useElementScriptTrigger',
|
||||
'useScript',
|
||||
'useScriptGoogleAnalytics',
|
||||
'useScriptPlausibleAnalytics',
|
||||
'useScriptCloudflareWebAnalytics',
|
||||
'useScriptFathomAnalytics',
|
||||
'useScriptMatomoAnalytics',
|
||||
'useScriptGoogleTagManager',
|
||||
'useScriptSegment',
|
||||
'useScriptFacebookPixel',
|
||||
'useScriptXPixel',
|
||||
'useScriptIntercom',
|
||||
'useScriptHotjar',
|
||||
'useScriptStripe',
|
||||
'useScriptLemonSqueezy',
|
||||
'useScriptVimeoPlayer',
|
||||
'useScriptYouTubeIframe',
|
||||
'useScriptGoogleMaps',
|
||||
'useScriptNpm',
|
||||
],
|
||||
from: '#app/composables/script-stubs',
|
||||
} satisfies InlinePreset
|
||||
|
||||
// This is a separate preset as we'll swap these out for import from `vue-router` itself in `pages` module
|
||||
const routerPreset = defineUnimportPreset({
|
||||
imports: ['onBeforeRouteLeave', 'onBeforeRouteUpdate'],
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { createUnplugin } from 'unplugin'
|
||||
import type { Unimport } from 'unimport'
|
||||
import { normalize } from 'pathe'
|
||||
import { tryUseNuxt } from '@nuxt/kit'
|
||||
import type { ImportsOptions } from 'nuxt/schema'
|
||||
import { isJS, isVue } from '../core/utils'
|
||||
|
||||
@ -37,7 +38,11 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: { ct
|
||||
return
|
||||
}
|
||||
|
||||
const { s } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule })
|
||||
const { s, imports } = await ctx.injectImports(code, id, { autoImport: options.autoImport && !isNodeModule })
|
||||
if (imports.some(i => i.from === '#app/composables/script-stubs') && tryUseNuxt()?.options.test === false) {
|
||||
import('../core/features').then(({ installNuxtModule }) => installNuxtModule('@nuxt/scripts'))
|
||||
}
|
||||
|
||||
if (s.hasChanged()) {
|
||||
return {
|
||||
code: s.toString(),
|
||||
|
Loading…
Reference in New Issue
Block a user