Skip to content

Commit

Permalink
feat: provide access to global setup() function
Browse files Browse the repository at this point in the history
closes #104, and see #111
  • Loading branch information
danielroe committed Jun 12, 2020
1 parent 67d3245 commit 7fd70d9
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 23 deletions.
1 change: 1 addition & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
title: 'Helpers',
collapsable: false,
children: [
'/helpers/onGlobalSetup',
'/helpers/shallowSsrRef',
'/helpers/ssrRef',
'/helpers/useAsync',
Expand Down
20 changes: 20 additions & 0 deletions docs/helpers/onGlobalSetup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
---

# onGlobalSetup

This helper will run a callback function in the global setup function.

```ts
import { onGlobalSetup } from 'nuxt-composition-api'

export default () => {
onGlobalSetup(() => {
provide('globalKey', true)
})
}
```

::: warning
This should be called from within a plugin rather than in a component context.
:::
1 change: 1 addition & 0 deletions src/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { useAsync } from './async'
export { defineComponent } from './component'
export { useContext, withContext } from './context'
export { useFetch } from './fetch'
export { globalPlugin, onGlobalSetup } from './hooks'
export { useMeta } from './meta'
export { ssrRef, shallowSsrRef, setSSRContext } from './ssr-ref'
export { useStatic } from './static'
Expand Down
52 changes: 52 additions & 0 deletions src/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { Plugin } from '@nuxt/types'
import type { SetupContext } from '@vue/composition-api'

import { setSSRContext } from './ssr-ref'

type SetupFunction = (
this: void,
props: Record<string, unknown>,
ctx: SetupContext
) => void | Record<any, any>

const globalSetup = new Set<SetupFunction>()

/**
* Run a callback function in the global setup function. This should be called from a Nuxt plugin.
* @param fn The function to run in the setup function. It receives the global props and context.
* @example
```ts
import { onGlobalSetup } from 'nuxt-composition-api'
export default () => {
onGlobalSetup(() => {
provide('globalKey', true)
})
}
```
*/
export const onGlobalSetup = (fn: SetupFunction) => {
globalSetup.add(fn)
}

/**
* @private
*/
export const globalPlugin: Plugin = context => {
const { setup } = context.app
context.app.setup = (...args) => {
let result = {}
if (setup instanceof Function) {
result = { ...setup(...args) }
}
for (const fn of globalSetup) {
result = { ...result, ...(fn(...args) || {}) }
}
return result
}

if (!process.server) return
if (context.app.context.ssrContext) {
setSSRContext(context.app.context.ssrContext)
}
}
25 changes: 2 additions & 23 deletions src/plugin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
/**
* @typedef {import('@nuxt/types').Plugin} Plugin
*/

<% if (options.corejsPolyfill === '3') { %>
// Necessary polyfill for Composition API support for IE11
import 'core-js/features/reflect/own-keys'
Expand All @@ -10,23 +6,6 @@ import 'core-js/features/reflect/own-keys'
import 'core-js/modules/es6.reflect.own-keys'
<% } %>

import { setSSRContext } from 'nuxt-composition-api'

/**
*
* @type {Plugin} plugin
*/
const plugin = context => {
if (!process.server) return

const { setup } = context.app
context.app.setup = (...args) => {
if (setup instanceof Function) setup(...args)
// Run instantiating functions that must be run within setup()
}
if (context.app.context.ssrContext) {
setSSRContext(context.app.context.ssrContext)
}
}
import { globalPlugin } from 'nuxt-composition-api'

export default plugin
export default globalPlugin
22 changes: 22 additions & 0 deletions test/e2e/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Selector } from 'testcafe'
import { navigateTo, expectOnPage } from './helpers'

// eslint-disable-next-line
fixture`onGlobalSetup`

const assertions = async () => {
await expectOnPage('global setup was run on server')
await expectOnPage('global setup was run on client')
await expectOnPage('globally injected value was received')
}

test('Runs plugin on server side page', async () => {
await navigateTo('/hooks')
await assertions()
})

test('Runs plugin on client rendered page', async t => {
await navigateTo('/')
await t.click(Selector('a').withText('hooks'))
await assertions()
})
1 change: 1 addition & 0 deletions test/fixture/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
rootDir: resolve(__dirname, '../..'),
buildDir: resolve(__dirname, '.nuxt'),
srcDir: __dirname,
plugins: [resolve(__dirname, './plugins/global.js')],
serverMiddleware: [
{
path: '/api/posts',
Expand Down
26 changes: 26 additions & 0 deletions test/fixture/pages/hooks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template>
<blockquote>
<p>
<code>global setup was {{ ranSsr ? 'run' : 'not run' }} on server</code>
<br />
<code>global setup was {{ ran ? 'run' : 'not run' }} on client</code>
<br />
<code>
globally injected value was
{{ globalInject ? 'received' : 'not received' }}
</code>
</p>
</blockquote>
</template>

<script>
import { defineComponent, inject } from 'nuxt-composition-api'
import { ran, ranSsr } from '../plugins/global'
export default defineComponent({
setup() {
const globalInject = inject('globalKey', false)
return { globalInject, ran, ranSsr }
},
})
</script>
1 change: 1 addition & 0 deletions test/fixture/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
<li><nuxt-link to="/other">link forward</nuxt-link></li>
<li><nuxt-link to="/ssr-ref">ssr refs</nuxt-link></li>
<li><nuxt-link to="/context/a">context</nuxt-link></li>
<li><nuxt-link to="/hooks">hooks</nuxt-link></li>
<li><nuxt-link to="/static/1">static</nuxt-link></li>
<li>
<nuxt-link to="/no-setup">ssr ref defined outside of setup</nuxt-link>
Expand Down
18 changes: 18 additions & 0 deletions test/fixture/plugins/global.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { onGlobalSetup, provide, ref, ssrRef } from 'nuxt-composition-api'

export const ranSsr = ssrRef(false)
export const ran = ref(false)

export default () => {
onGlobalSetup(() => {
ran.value = true
ranSsr.value = true

provide('globalKey', true)

return {
ran,
ranSsr,
}
})
}

0 comments on commit 7fd70d9

Please sign in to comment.