Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

Commit

Permalink
feat(bridge): use useMeta in bridge projects
Browse files Browse the repository at this point in the history
* includes `nuxt.app` shim and `vue` module that exports composition api functions
  • Loading branch information
danielroe committed Oct 6, 2021
1 parent 485c976 commit ace59d9
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 17 deletions.
1 change: 1 addition & 0 deletions packages/bridge/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@nuxt/nitro": "3.0.0",
"@nuxt/postcss8": "^1.1.3",
"@vue/composition-api": "^1.2.3",
"@vueuse/head": "^0.6.0",
"acorn": "^8.5.0",
"defu": "^5.0.0",
"enhanced-resolve": "^5.8.3",
Expand Down
4 changes: 3 additions & 1 deletion packages/bridge/src/global-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import globalImports from '../../nuxt3/src/global-imports/module'

// TODO: implement these: https://github.com/nuxt/framework/issues/549
const disabled = [
'useMeta',
'useAsyncData',
'asyncData'
]
Expand All @@ -17,6 +16,9 @@ const identifiers = {
'useRouter',
'useRuntimeConfig'
],
'#meta': [
'useMeta'
],
'@vue/composition-api': [
// lifecycle
'onActivated',
Expand Down
62 changes: 62 additions & 0 deletions packages/bridge/src/meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { resolve } from 'pathe'
import defu from 'defu'
import { resolveModule, defineNuxtModule, addTemplate, addPlugin } from '@nuxt/kit'
import type { MetaObject } from '../../nuxt3/src/meta/runtime'
import { distDir } from './dirs'

const checkDocsMsg = 'Please see https://v3.nuxtjs.org for more information.'
const msgPrefix = '[bridge] [meta]'

export default defineNuxtModule({
name: 'meta',
defaults: {
charset: 'utf-8',
viewport: 'width=device-width, initial-scale=1'
},
setup (options, nuxt) {
// Alias vue to a vue3-compat version of vue2
nuxt.options.alias['#vue'] = nuxt.options.alias.vue || resolveModule('vue/dist/vue.runtime.esm.js', { paths: nuxt.options.modulesDir })
nuxt.options.alias['@vue/shared'] = 'vue'
nuxt.options.alias['@vue/reactivity'] = 'vue'
nuxt.options.alias.vue = resolve(distDir, 'runtime/vue.mjs')

// Turn off vue-meta and migrate configuration
nuxt.options.features.meta = false
if (nuxt.options.head) {
if (typeof nuxt.options.head === 'function') {
throw new TypeError(`${msgPrefix} Please move head() function from \`nuxt.config\` to \`app.vue\`. ${checkDocsMsg}`)
} else {
console.warn(`${msgPrefix} Please rename \`head\` to \`meta\` in your \`nuxt.config\`. ${checkDocsMsg}`)
nuxt.options.meta = defu(nuxt.options.meta, nuxt.options.head)
}
}

const runtimeDir = resolve(distDir, 'runtime/meta')

// Transpile @nuxt/meta and @vueuse/head
nuxt.options.build.transpile.push(runtimeDir, 'vue', '@vueuse/head')

// Add #meta alias
nuxt.options.alias['#meta'] = runtimeDir

// Global meta
const globalMeta: MetaObject = defu(nuxt.options.meta, {
meta: [
{ charset: options.charset },
{ name: 'viewport', content: options.viewport }
]
})

// Add global meta configuration
addTemplate({
filename: 'meta.config.mjs',
getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: 'setup' })
})

// Add generic plugin
addPlugin({ src: resolve(runtimeDir, 'plugin') })

// Add library specific plugin
addPlugin({ src: resolve(runtimeDir, 'lib/vueuse-head.plugin') })
}
})
17 changes: 15 additions & 2 deletions packages/bridge/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { createRequire } from 'module'
import { defineNuxtModule, installModule, checkNuxtCompatibilityIssues } from '@nuxt/kit'
import { defineNuxtModule, installModule, checkNuxtCompatibilityIssues, addPluginTemplate } from '@nuxt/kit'
import { resolve } from 'pathe'
import { setupNitroBridge } from './nitro'
import { setupAppBridge } from './app'
import { setupCAPIBridge } from './capi'
import { setupBetterResolve } from './resolve'
import { setupGlobalImports } from './global-imports'
import { setupTypescript } from './typescript'
import metaModule from './meta'
import { distDir } from './dirs'

export interface BridgeConfig {
nitro: boolean
vite: boolean
app: boolean | {}
capi: boolean | {}
globalImports: boolean
meta: boolean
constraints: boolean
postcss8: boolean
swc: boolean
resolve: boolean
typescript: boolean
}
Expand All @@ -30,6 +33,7 @@ export default defineNuxtModule({
capi: {},
globalImports: true,
constraints: true,
meta: true,
// TODO: Remove from 2.16
postcss8: true,
typescript: true,
Expand Down Expand Up @@ -78,6 +82,15 @@ export default defineNuxtModule({
}
})
}
if (opts.meta) {
await installModule(nuxt, metaModule)
} else if (nuxt.options.features.meta) {
// Nitro server plugin (for vue-meta)
addPluginTemplate({
filename: 'nitro-bridge.server.mjs',
src: resolve(distDir, 'runtime/nitro-bridge.server.mjs')
})
}
}
})

Expand Down
6 changes: 0 additions & 6 deletions packages/bridge/src/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ export function setupNitroBridge () {
src: resolve(nitroContext._internal.runtimeDir, 'app/nitro.client.mjs')
})

// Nitro server plugin (for vue-meta)
addPluginTemplate({
filename: 'nitro-bridge.server.mjs',
src: resolve(distDir, 'runtime/nitro-bridge.server.mjs')
})

// Fix module resolution
nuxt.hook('webpack:config', (configs) => {
for (const config of configs) {
Expand Down
21 changes: 21 additions & 0 deletions packages/bridge/src/runtime/app.plugin.mjs
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
import Vue from 'vue'
import { createHooks } from 'hookable/dist/index.mjs'
import { setNuxtInstance } from '#app'

export default (ctx, inject) => {
const nuxt = {
app: {
component: Vue.component.bind(Vue),
config: {
globalProperties: {}
},
directive: Vue.directive.bind(Vue),
mixin: Vue.mixin.bind(Vue),
mount: () => {},
provide: inject,
unmount: () => {},
use (vuePlugin) {
vuePlugin.install(this)
},
version: Vue.version
},
provide: inject,
globalName: 'nuxt',
payload: process.client ? ctx.nuxtState : ctx.ssrContext.nuxt,
isHydrating: ctx.isHMR,
legacyNuxt: ctx.app
}

nuxt.hooks = createHooks()
nuxt.hook = nuxt.hooks.hook
nuxt.callHook = nuxt.hooks.callHook
Expand All @@ -17,6 +34,10 @@ export default (ctx, inject) => {
ctx.app.created = [ctx.app.created]
}

if (process.server) {
nuxt.ssrContext = ctx.ssrContext
}

ctx.app.created.push(function () {
nuxt.legacyApp = this
})
Expand Down
1 change: 1 addition & 0 deletions packages/bridge/src/runtime/meta
7 changes: 7 additions & 0 deletions packages/bridge/src/runtime/vue.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Vue from '#vue'

export * from '@vue/composition-api'

export const isFunction = fn => fn instanceof Function

export { Vue as default }
16 changes: 16 additions & 0 deletions packages/kit/src/config/schema/_app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ export default {
script: []
},

/**
* Set default configuration for `<head>` on every page.
*
* @version 3
*/
meta: {
/** Each item in the array maps to a newly-created `<meta>` element, where object properties map to attributes. */
meta: [],
/** Each item in the array maps to a newly-created `<link>` element, where object properties map to attributes. */
link: [],
/** Each item in the array maps to a newly-created `<style>` element, where object properties map to attributes. */
style: [],
/** Each item in the array maps to a newly-created `<script>` element, where object properties map to attributes. */
script: []
},

/**
* Configuration for the Nuxt `fetch()` hook.
* @version 2
Expand Down
11 changes: 6 additions & 5 deletions packages/nuxt3/src/meta/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { resolve } from 'pathe'
import { addPlugin, addTemplate, defineNuxtModule } from '@nuxt/kit'
import { addPlugin, addTemplate, defineNuxtModule, isNuxt3 } from '@nuxt/kit'
import defu from 'defu'
import { distDir } from '../dirs'
import type { MetaObject } from './runtime'

Expand All @@ -10,7 +11,7 @@ export default defineNuxtModule({
viewport: 'width=device-width, initial-scale=1'
},
setup (options, nuxt) {
const runtimeDir = resolve(distDir, 'meta/runtime')
const runtimeDir = nuxt.options.alias['#meta'] || resolve(distDir, 'meta/runtime')

// Transpile @nuxt/meta and @vueuse/head
nuxt.options.build.transpile.push(runtimeDir, '@vueuse/head')
Expand All @@ -19,17 +20,17 @@ export default defineNuxtModule({
nuxt.options.alias['#meta'] = runtimeDir

// Global meta
const globalMeta: MetaObject = {
const globalMeta: MetaObject = defu(nuxt.options.meta, {
meta: [
{ charset: options.charset },
{ name: 'viewport', content: options.viewport }
]
}
})

// Add global meta configuration
addTemplate({
filename: 'meta.config.mjs',
getContents: () => 'export default ' + JSON.stringify({ globalMeta })
getContents: () => 'export default ' + JSON.stringify({ globalMeta, mixinKey: isNuxt3() ? 'created' : 'setup' })
})

// Add generic plugin
Expand Down
7 changes: 4 additions & 3 deletions packages/nuxt3/src/meta/runtime/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export default defineNuxtPlugin((nuxt) => {
useMeta(metaConfig.globalMeta)

nuxt.app.mixin({
created () {
[metaConfig.mixinKey] () {
const instance = getCurrentInstance()
if (!instance?.type || !('head' in instance.type)) { return }
const options = instance?.type || /* nuxt2 */ instance?.proxy?.$options
if (!options || !('head' in options)) { return }

useMeta((instance.type as any).head)
useMeta(options.head)
}
})

Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/bridge/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
</template>

<script>
import { useMeta } from '#app'
export default defineComponent({
setup () {
useMeta({ meta: [{ name: 'description', content: 'This is a page to demo Nuxt Bridge.' }] })
return {
version: ref('2')
}
},
head: {
title: 'Bridge test fixture'
}
})
</script>
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@ __metadata:
"@types/fs-extra": ^9.0.13
"@types/node-fetch": ^3.0.2
"@vue/composition-api": ^1.2.3
"@vueuse/head": ^0.6.0
acorn: ^8.5.0
defu: ^5.0.0
enhanced-resolve: ^5.8.3
Expand Down

0 comments on commit ace59d9

Please sign in to comment.