Skip to content

feat(tpc): build-time third-party-capital composables #81

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
cbf1619
feat: wip
huang-julien Jun 1, 2024
2832a38
working poc for gtag + disable #77 bug in playground
huang-julien Jun 1, 2024
f3691b6
various fixes
huang-julien Jun 1, 2024
c27c65b
feat: handle link and additionnal scripts
huang-julien Jun 3, 2024
65a9f56
Merge branch 'main' into feat/poc_build_time_tpc
julien-huang-leetchi Jun 4, 2024
f5f90af
refactor: replace registry and various changes
huang-julien Jun 6, 2024
97cecbf
chore: lint
huang-julien Jun 6, 2024
be8066d
chore: update tpc and move it to peer deps
huang-julien Jun 6, 2024
f78ef09
refactor: directly use json Data from tpc
huang-julien Jun 6, 2024
2d9d9cb
chore: lint
huang-julien Jun 6, 2024
106ecc4
fix: forgot to trigger functions
huang-julien Jun 6, 2024
278eddb
build: add missing external
huang-julien Jun 6, 2024
6084daf
fix: types and tpye imports
huang-julien Jun 6, 2024
4e087be
chore: inc tpc version
huang-julien Jun 7, 2024
e8d1355
chore: update lockfile
huang-julien Jun 7, 2024
e5014de
chore: remove old registry and composables
huang-julien Jun 8, 2024
6da9638
fix: imports
huang-julien Jun 8, 2024
798c807
test: test transformation
huang-julien Jun 8, 2024
b395827
refactor: move generated composables to nuxt-script build dir
huang-julien Jun 9, 2024
7e724f9
chore: remove commented import
huang-julien Jun 9, 2024
263a7fc
fix: feedbacks
huang-julien Jun 9, 2024
14592fc
test: update snapshots
huang-julien Jun 9, 2024
3cc3e34
fix: imports
huang-julien Jun 9, 2024
a33b089
oops
huang-julien Jun 9, 2024
0045e68
test: update snapshot
huang-julien Jun 9, 2024
a951aa9
chore: move tpc to dependencies
julien-huang-leetchi Jun 11, 2024
fe5a133
Merge remote-tracking branch 'origin/main' into feat/poc_build_time_tpc
julien-huang-leetchi Jun 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@
"@unhead/vue",
"@unhead/schema",
"#nuxt-scripts",
"#nuxt-scripts-validator"
"#nuxt-scripts-validator",
"third-party-capital",
"knitwork"
]
},
"dependencies": {
Expand All @@ -81,7 +83,7 @@
"shiki": "^1.6.2",
"sirv": "^2.0.4",
"std-env": "^3.7.0",
"third-party-capital": "^1.0.28",
"third-party-capital": "^1.0.30",
"ufo": "^1.5.3",
"unimport": "^3.7.2",
"unplugin": "^1.10.1",
Expand All @@ -99,6 +101,7 @@
"bumpp": "^9.4.1",
"changelogen": "^0.5.5",
"eslint": "9.4.0",
"knitwork": "^1.1.0",
"nuxt": "^3.11.2",
"playwright-core": "^1.44.1",
"typescript": "^5.4.5",
Expand Down
2 changes: 1 addition & 1 deletion playground/pages/third-parties/google-tag-manager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ $script.then(({ google_tag_manager, dataLayer }) => {
<div>
<ClientOnly>
<div>
status: {{ $script.status.value }}
status: {{ $script.status }}
</div>
</ClientOnly>
</div>
Expand Down
1,472 changes: 1,314 additions & 158 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import type {
RegistryScript,
RegistryScripts,
} from './runtime/types'
import addGoogleAnalyticsRegistry from './tpc/google-analytics'
import addGoogleTagManagerRegistry from './tpc/google-tag-manager'

export interface ModuleOptions {
/**
Expand Down Expand Up @@ -74,6 +76,12 @@ export interface ModuleHooks {
'scripts:registry': (registry: RegistryScripts) => void | Promise<void>
}

declare module '@nuxt/schema' {
interface NuxtHooks {
'scripts:registry': ModuleHooks['scripts:registry']
}
}

export default defineNuxtModule<ModuleOptions>({
meta: {
name: '@nuxt/scripts',
Expand Down Expand Up @@ -125,9 +133,13 @@ export default defineNuxtModule<ModuleOptions>({
})

const scripts = registry(resolve)

addGoogleAnalyticsRegistry()
addGoogleTagManagerRegistry()

nuxt.hooks.hook('modules:done', async () => {
const registryScripts = [...scripts]
// @ts-expect-error runtime

await nuxt.hooks.callHook('scripts:registry', registryScripts)
const withComposables = registryScripts.filter(i => !!i.import?.name) as Required<RegistryScript>[]
addImports(withComposables.map((i) => {
Expand Down
25 changes: 1 addition & 24 deletions src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,15 @@ import type { IntercomInput } from './runtime/registry/intercom'
import type { SegmentInput } from './runtime/registry/segment'
import type { NpmInput } from './runtime/registry/npm'
import type { PlausibleAnalyticsInput } from './runtime/registry/plausible-analytics'
import type { GoogleAnalyticsInput } from './runtime/registry/google-analytics'
import type { RegistryScripts } from './runtime/types'
import type { GoogleAdsenseInput } from './runtime/registry/google-adsense'

// avoid nuxt/kit dependency here so we can use in docs

export const registry: (resolve?: (s: string) => string) => RegistryScripts = (resolve?: (s: string) => string) => {
resolve = resolve || ((s: string) => s)

return [
// analytics
{
label: 'Google Analytics',
category: 'analytics',
logo: `<svg xmlns="http://www.w3.org/2000/svg" width="28.85" height="32" viewBox="0 0 256 284"><path fill="#F9AB00" d="M256.003 247.933a35.224 35.224 0 0 1-39.376 35.161c-18.044-2.67-31.266-18.371-30.826-36.606V36.845C185.365 18.591 198.62 2.881 216.687.24a35.221 35.221 0 0 1 39.316 35.16z"/><path fill="#E37400" d="M35.101 213.193c19.386 0 35.101 15.716 35.101 35.101c0 19.386-15.715 35.101-35.101 35.101S0 267.68 0 248.295c0-19.386 15.715-35.102 35.101-35.102m92.358-106.387c-19.477 1.068-34.59 17.406-34.137 36.908v94.285c0 25.588 11.259 41.122 27.755 44.433a35.161 35.161 0 0 0 42.146-34.56V142.089a35.222 35.222 0 0 0-35.764-35.282"/></svg>`,
scriptBundling: (options?: GoogleAnalyticsInput) => withQuery('https://www.googletagmanager.com/gtag/js', {
id: options?.id,
}),
import: {
name: 'useScriptGoogleAnalytics',
from: resolve('./runtime/registry/google-analytics'),
},
},
{
label: 'Plausible Analytics',
category: 'analytics',
Expand Down Expand Up @@ -69,16 +56,6 @@ export const registry: (resolve?: (s: string) => string) => RegistryScripts = (r
from: resolve('./runtime/registry/matomo-analytics'),
},
},
// tracking
{
label: 'Google Tag Manager',
category: 'tracking',
logo: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="#8AB4F8" d="m150.262 245.516l-44.437-43.331l95.433-97.454l46.007 45.091z"/><path fill="#4285F4" d="M150.45 53.938L106.176 8.731L9.36 104.629c-12.48 12.48-12.48 32.713 0 45.207l95.36 95.986l45.09-42.182l-72.654-76.407z"/><path fill="#8AB4F8" d="m246.625 105.37l-96-96c-12.494-12.494-32.756-12.494-45.25 0c-12.495 12.495-12.495 32.757 0 45.252l96 96c12.494 12.494 32.756 12.494 45.25 0c12.495-12.495 12.495-32.757 0-45.251"/><circle cx="127.265" cy="224.731" r="31.273" fill="#246FDB"/></svg>`,
import: {
name: 'useScriptGoogleTagManager',
from: resolve('./runtime/registry/google-tag-manager'),
},
},
{
label: 'Segment',
scriptBundling: (options?: SegmentInput) => {
Expand Down
59 changes: 0 additions & 59 deletions src/runtime/registry/google-analytics.ts

This file was deleted.

49 changes: 0 additions & 49 deletions src/runtime/registry/google-tag-manager.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import type { MetaPixelInput } from './registry/meta-pixel'
import type { FathomAnalyticsInput } from './registry/fathom-analytics'
import type { HotjarInput } from './registry/hotjar'
import type { IntercomInput } from './registry/intercom'
import type { GoogleAnalyticsInput } from './registry/google-analytics'
import type { GoogleMapsInput } from './registry/google-maps'
import type { GoogleTagManagerInput } from './registry/google-tag-manager'
import type { MatomoAnalyticsInput } from './registry/matomo-analytics'
import type { StripeInput } from './registry/stripe'
import type { VimeoPlayerInput } from './registry/vimeo-player'
Expand All @@ -21,6 +19,8 @@ import type { YouTubePlayerInput } from './registry/youtube-player'
import type { PlausibleAnalyticsInput } from './registry/plausible-analytics'
import type { NpmInput } from './registry/npm'
import type { LemonSqueezyInput } from './registry/lemon-squeezy'
import type { Input as GoogleTagManagerInput } from '#build/nuxt-scripts/tpc/google-tag-manager'
import type { Input as GoogleAnalyticsInput } from '#build/nuxt-scripts/tpc/google-analytics'

export type NuxtUseScriptOptions<T = any> = Omit<UseScriptOptions<T>, 'trigger'> & {
/**
Expand Down
54 changes: 54 additions & 0 deletions src/tpc/google-analytics.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { addImports, addTemplate, useNuxt } from '@nuxt/kit'
import type { Output } from 'third-party-capital'
import { GooglaAnalyticsData, GoogleAnalytics } from 'third-party-capital'
import type { RegistryScript } from '../runtime/types'
import { getTpcScriptContent } from './utils'

export default function googleAnalitycsRegistry() {
const nuxt = useNuxt()
const { dst } = addTemplate({
getContents() {
return getTpcScriptContent({
data: GooglaAnalyticsData as Output,
scriptFunctionName: 'useScriptGoogleAnalytics',
use: () => {
return { dataLayer: window.dataLayer, gtag: window.gtag }
},
// allow dataLayer to be accessed on the server
stub: ({ fn }) => {
return fn === 'dataLayer' ? [] : undefined
},
tpcKey: 'gtag',
tpcTypeImport: 'GoogleAnalyticsApi',
augmentWindowTypes: true,
})
},
filename: 'nuxt-scripts/tpc/google-analytics.ts',
})

addImports({
from: dst,
name: 'useScriptGoogleAnalytics',
})
const registry: RegistryScript = {
label: 'Google Tag Manager',
category: 'tracking',
logo: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="#8AB4F8" d="m150.262 245.516l-44.437-43.331l95.433-97.454l46.007 45.091z"/><path fill="#4285F4" d="M150.45 53.938L106.176 8.731L9.36 104.629c-12.48 12.48-12.48 32.713 0 45.207l95.36 95.986l45.09-42.182l-72.654-76.407z"/><path fill="#8AB4F8" d="m246.625 105.37l-96-96c-12.494-12.494-32.756-12.494-45.25 0c-12.495 12.495-12.495 32.757 0 45.252l96 96c12.494 12.494 32.756 12.494 45.25 0c12.495-12.495 12.495-32.757 0-45.251"/><circle cx="127.265" cy="224.731" r="31.273" fill="#246FDB"/></svg>`,
import: {
name: 'useScriptGoogleAnalytics',
from: dst,
},
scriptBundling(options) {
const data = GoogleAnalytics(options)
const mainScript = data.scripts?.find(({ key }) => key === 'gtag')

if (mainScript && 'url' in mainScript && mainScript.url)
return mainScript.url

return false
},
}
nuxt.hook('scripts:registry', (scripts) => {
scripts.push(registry)
})
}
57 changes: 57 additions & 0 deletions src/tpc/google-tag-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { addImports, addTemplate, useNuxt } from '@nuxt/kit'
import type { Output } from 'third-party-capital'
import { GoogleTagManager, GoogleTagManagerData } from 'third-party-capital'

import type { RegistryScript } from '../runtime/types'
import { getTpcScriptContent } from './utils'

export default function googleTagManagerRegistry() {
const nuxt = useNuxt()

const { dst } = addTemplate({
getContents() {
return getTpcScriptContent({
data: GoogleTagManagerData as Output,
scriptFunctionName: 'useScriptGoogleTagManager',
use: () => {
return { dataLayer: window.dataLayer, google_tag_manager: window.google_tag_manager }
},
stub: ({ fn }) => {
return fn === 'dataLayer' ? [] : undefined
},
tpcKey: 'gtm',
tpcTypeImport: 'GoogleTagManagerApi',
augmentWindowTypes: true,
})
},
filename: 'nuxt-scripts/tpc/google-tag-manager.ts',
})

addImports({
from: dst,
name: 'useScriptGoogleTagManager',
})

const registry: RegistryScript = {
label: 'Google Tag Manager',
category: 'tracking',
logo: `<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="#8AB4F8" d="m150.262 245.516l-44.437-43.331l95.433-97.454l46.007 45.091z"/><path fill="#4285F4" d="M150.45 53.938L106.176 8.731L9.36 104.629c-12.48 12.48-12.48 32.713 0 45.207l95.36 95.986l45.09-42.182l-72.654-76.407z"/><path fill="#8AB4F8" d="m246.625 105.37l-96-96c-12.494-12.494-32.756-12.494-45.25 0c-12.495 12.495-12.495 32.757 0 45.252l96 96c12.494 12.494 32.756 12.494 45.25 0c12.495-12.495 12.495-32.757 0-45.251"/><circle cx="127.265" cy="224.731" r="31.273" fill="#246FDB"/></svg>`,
import: {
name: 'useScriptGoogleTagManager',
from: dst,
},
scriptBundling(options) {
const data = GoogleTagManager(options)
const mainScript = data.scripts?.find(({ key }) => key === 'gtm')

if (mainScript && 'url' in mainScript && mainScript.url)
return mainScript.url

return false
},
}

nuxt.hook('scripts:registry', (scripts) => {
scripts.push(registry)
})
}
Loading