Skip to content

Commit bc06287

Browse files
committed
feat(nuxt): experimental config to remove runtime scripts when SSR
1 parent 33cd2b5 commit bc06287

File tree

5 files changed

+95
-19
lines changed

5 files changed

+95
-19
lines changed

packages/nuxt/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
},
4343
"dependencies": {
4444
"@nuxt/kit": "3.0.0-rc.6",
45-
"@vueuse/schema-org": "workspace:*"
45+
"@vueuse/schema-org": "workspace:*",
46+
"magic-string": "^0.26.2",
47+
"unplugin": "^0.7.2"
4648
},
4749
"devDependencies": {
4850
"@nuxt/module-builder": "latest",

packages/nuxt/src/module.ts

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@ import type { SchemaOrgOptions } from '@vueuse/schema-org'
99
import { schemaOrgAutoImports, schemaOrgComponents } from '@vueuse/schema-org'
1010
import type { NuxtModule } from '@nuxt/schema'
1111
import { dirname } from 'pathe'
12+
import { createUnplugin } from 'unplugin'
13+
import MagicString from 'magic-string'
1214

1315
export interface ModuleOptions extends SchemaOrgOptions {
16+
/**
17+
* Should schema.org only be rendered by the server.
18+
*
19+
* Useful for optimising performance as it may not be needed by search engines. Changes runtime package size to 0kb.
20+
*/
21+
disableRuntimeScriptsWhenSSR: boolean
1422
/**
1523
* Whether composables will be automatically imported for you.
1624
* @default true
@@ -27,6 +35,8 @@ export interface ModuleHooks {
2735

2836
}
2937

38+
const SchemaOrgPkg = '@vueuse/schema-org'
39+
3040
export default defineNuxtModule<ModuleOptions>({
3141
meta: {
3242
configKey: 'schemaOrg',
@@ -35,6 +45,7 @@ export default defineNuxtModule<ModuleOptions>({
3545
},
3646
},
3747
defaults: {
48+
disableRuntimeScriptsWhenSSR: false,
3849
autoImportComposables: true,
3950
autoImportComponents: true,
4051
},
@@ -44,22 +55,24 @@ export default defineNuxtModule<ModuleOptions>({
4455
const runtimeDir = resolve('./runtime')
4556
nuxt.options.build.transpile.push(runtimeDir)
4657

47-
// server & client logic are seperated
48-
addPlugin(resolve(runtimeDir, 'plugin.client'))
58+
const registerClientScripts = !config.disableRuntimeScriptsWhenSSR || nuxt.options.dev
59+
60+
// allow users to opt-out of client side scripts, if it's not dev
61+
if (registerClientScripts)
62+
addPlugin(resolve(runtimeDir, 'plugin.client'))
4963
addPlugin(resolve(runtimeDir, 'plugin.server'))
5064

5165
// avoid unwanted behavior with different package managers
52-
const schemaOrgPath = dirname(await resolvePath('@vueuse/schema-org'))
53-
nuxt.options.alias['@vueuse/schema-org'] = schemaOrgPath
66+
const schemaOrgPath = dirname(await resolvePath(SchemaOrgPkg))
67+
nuxt.options.alias[SchemaOrgPkg] = schemaOrgPath
68+
nuxt.options.build.transpile.push(...[schemaOrgPath, SchemaOrgPkg])
5469

55-
nuxt.hook('vite:extend', ({ config }: any) => {
70+
nuxt.hook('vite:extendConfig', (config) => {
5671
config.optimizeDeps = config.optimizeDeps || {}
5772
config.optimizeDeps.exclude = config.optimizeDeps.exclude || []
58-
config.optimizeDeps.exclude.push(...[schemaOrgPath, '@vueuse/schema-org'])
73+
config.optimizeDeps.exclude.push(...[schemaOrgPath, SchemaOrgPkg])
5974
})
6075

61-
nuxt.options.build.transpile.push(...[schemaOrgPath, '@vueuse/schema-org'])
62-
6376
addTemplate({
6477
filename: 'schemaOrg.config.mjs',
6578
getContents: () => `export default ${JSON.stringify({ config })}`,
@@ -69,7 +82,7 @@ export default defineNuxtModule<ModuleOptions>({
6982
nuxt.hooks.hookOnce('autoImports:sources', (autoImports) => {
7083
autoImports.unshift({
7184
from: resolve('./runtime/composables'),
72-
imports: schemaOrgAutoImports['@vueuse/schema-org'],
85+
imports: schemaOrgAutoImports[SchemaOrgPkg],
7386
})
7487
})
7588
}
@@ -83,5 +96,56 @@ export default defineNuxtModule<ModuleOptions>({
8396
})
8497
})
8598
}
99+
100+
if (!registerClientScripts) {
101+
const mockTemplate = addTemplate({
102+
filename: 'schema-org-mock.mjs',
103+
getContents() {
104+
return schemaOrgAutoImports[SchemaOrgPkg]
105+
.map(s => `export function ${s}() {}`)
106+
.join('\n')
107+
},
108+
})
109+
addComponent({
110+
name: 'SchemaOrgMock',
111+
// use mock components if we don't need real ones
112+
export: 'SchemaOrgMock',
113+
filePath: schemaOrgPath,
114+
})
115+
nuxt.options.alias['#schema-org/mock'] = mockTemplate.dst!
116+
117+
const mockerPlugin = createUnplugin(() => {
118+
return {
119+
name: 'nuxt-schema-org:mocker',
120+
enforce: 'post',
121+
transformInclude(id) {
122+
// only include users custom vue files
123+
return id.endsWith('.vue') && id.includes(nuxt.options.srcDir)
124+
},
125+
transform(code, id) {
126+
const s = new MagicString(code)
127+
128+
// swap our composables with mock composables
129+
s.replace(resolve(runtimeDir, 'composables'), '#schema-org/mock')
130+
// replace components with mock components
131+
s.replace(/_resolveComponent\("SchemaOrg(.*?)"\)/gm, '_resolveComponent("SchemaOrgMock")')
132+
133+
if (s.hasChanged()) {
134+
return {
135+
code: s.toString(),
136+
map: s.generateMap({ includeContent: true, source: id }),
137+
}
138+
}
139+
},
140+
}
141+
})
142+
143+
nuxt.hook('vite:extendConfig', (config, { isClient }) => {
144+
if (isClient) {
145+
config.plugins = config.plugins || []
146+
config.plugins.push(mockerPlugin.vite())
147+
}
148+
})
149+
}
86150
},
87151
}) as NuxtModule<ModuleOptions>

packages/schema-org/components/SchemaOrgInspector/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@ import { defineComponent, h, ref, watch } from 'vue-demi'
22
import { injectSchemaOrg } from '../../useSchemaOrg'
33
import type { SchemaOrgClient } from '../../types'
44

5+
export const SchemaOrgInspectorMock = defineComponent({
6+
name: 'SchemaOrgInspector',
7+
setup() {
8+
return () => new Promise(() => {})
9+
},
10+
})
11+
512
export const SchemaOrgInspector = defineComponent({
613
name: 'SchemaOrgInspector',
714
props: {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1+
import { defineSchemaOrgComponent } from './defineSchemaOrgComponent'
2+
13
export * from './SchemaOrgInspector'
4+
export const SchemaOrgMock = defineSchemaOrgComponent('SchemaOrgMock')

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)