mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-23 06:05:11 +00:00
feat(generator): export:route
hook and setPayload
(#7422)
* feat(generator): shared payload support for `nuxt export` * feat: add `export:` hooks for upward compatibility * fix: use setPayload to avoid breaking usage * test: update test * fix: deep assign * chore: update tests * fix: route payload has more periority than shared one * test: update generator hook tests * lint: remove unnecessary import
This commit is contained in:
parent
618eb5fad0
commit
a82f8d8b1f
@ -2,6 +2,7 @@ import path from 'path'
|
||||
import chalk from 'chalk'
|
||||
import consola from 'consola'
|
||||
import fsExtra from 'fs-extra'
|
||||
import defu from 'defu'
|
||||
import htmlMinifier from 'html-minifier'
|
||||
import { parse } from 'node-html-parser'
|
||||
|
||||
@ -23,6 +24,12 @@ export default class Generator {
|
||||
isUrl(this.options.build.publicPath) ? '' : this.options.build.publicPath
|
||||
)
|
||||
this.generatedRoutes = new Set()
|
||||
|
||||
// Shared payload
|
||||
this._payload = null
|
||||
this.setPayload = (payload) => {
|
||||
this._payload = defu(payload, this._payload)
|
||||
}
|
||||
}
|
||||
|
||||
async generate ({ build = true, init = true } = {}) {
|
||||
@ -47,6 +54,7 @@ export default class Generator {
|
||||
|
||||
// Done hook
|
||||
await this.nuxt.callHook('generate:done', this, errors)
|
||||
await this.nuxt.callHook('export:done', this, { errors })
|
||||
|
||||
return { errors }
|
||||
}
|
||||
@ -57,6 +65,7 @@ export default class Generator {
|
||||
|
||||
// Call before hook
|
||||
await this.nuxt.callHook('generate:before', this, this.options.generate)
|
||||
await this.nuxt.callHook('export:before', this)
|
||||
|
||||
if (build) {
|
||||
// Add flag to set process.static
|
||||
@ -115,6 +124,7 @@ export default class Generator {
|
||||
|
||||
// extendRoutes hook
|
||||
await this.nuxt.callHook('generate:extendRoutes', routes)
|
||||
await this.nuxt.callHook('export:extendRoutes', { routes })
|
||||
|
||||
return routes
|
||||
}
|
||||
@ -223,6 +233,7 @@ export default class Generator {
|
||||
|
||||
consola.info(`Generating output directory: ${path.basename(this.distPath)}/`)
|
||||
await this.nuxt.callHook('generate:distRemoved', this)
|
||||
await this.nuxt.callHook('export:distCopied', this)
|
||||
|
||||
// Copy static and built files
|
||||
if (await fsExtra.exists(this.staticRoutes)) {
|
||||
@ -241,6 +252,7 @@ export default class Generator {
|
||||
fsExtra.writeFile(nojekyllPath, '')
|
||||
|
||||
await this.nuxt.callHook('generate:distCopied', this)
|
||||
await this.nuxt.callHook('export:distCopied', this)
|
||||
}
|
||||
|
||||
decorateWithPayloads (routes, generateRoutes) {
|
||||
@ -265,6 +277,18 @@ export default class Generator {
|
||||
let html
|
||||
const pageErrors = []
|
||||
|
||||
const setPayload = (_payload) => {
|
||||
payload = defu(_payload, payload)
|
||||
}
|
||||
|
||||
// Apply shared payload
|
||||
if (this._payload) {
|
||||
payload = defu(payload, this._payload)
|
||||
}
|
||||
|
||||
await this.nuxt.callHook('generate:route', { route, setPayload })
|
||||
await this.nuxt.callHook('export:route', { route, setPayload })
|
||||
|
||||
try {
|
||||
const renderContext = {
|
||||
payload,
|
||||
@ -301,10 +325,8 @@ export default class Generator {
|
||||
pageErrors.push({ type: 'unhandled', route, error: err })
|
||||
errors.push(...pageErrors)
|
||||
|
||||
await this.nuxt.callHook('generate:routeFailed', {
|
||||
route,
|
||||
errors: pageErrors
|
||||
})
|
||||
await this.nuxt.callHook('generate:routeFailed', { route, errors: pageErrors })
|
||||
await this.nuxt.callHook('export:routeFailed', { route, errors: pageErrors })
|
||||
consola.error(this._formatErrors(pageErrors))
|
||||
|
||||
return false
|
||||
@ -332,6 +354,7 @@ export default class Generator {
|
||||
// Call hook to let user update the path & html
|
||||
const page = { route, path: fileName, html }
|
||||
await this.nuxt.callHook('generate:page', page)
|
||||
await this.nuxt.callHook('export:page', { page })
|
||||
|
||||
page.path = path.join(this.distPath, page.path)
|
||||
|
||||
@ -339,11 +362,8 @@ export default class Generator {
|
||||
await fsExtra.mkdirp(path.dirname(page.path))
|
||||
await fsExtra.writeFile(page.path, page.html, 'utf8')
|
||||
|
||||
await this.nuxt.callHook('generate:routeCreated', {
|
||||
route,
|
||||
path: page.path,
|
||||
errors: pageErrors
|
||||
})
|
||||
await this.nuxt.callHook('generate:routeCreated', { route, path: page.path, errors: pageErrors })
|
||||
await this.nuxt.callHook('export:routeCreated', { route, path: page.path, errors: pageErrors })
|
||||
|
||||
if (pageErrors.length) {
|
||||
consola.error('Error generating ' + route)
|
||||
|
@ -14,3 +14,7 @@ export const createNuxt = () => ({
|
||||
render: {}
|
||||
}
|
||||
})
|
||||
|
||||
export function hookCalls (nuxt, name) {
|
||||
return nuxt.callHook.mock.calls.filter(c => c[0] === name).map(c => c.splice(1))
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ describe('generator: generate routes', () => {
|
||||
expect(generator.generateRoutes).toBeCalledTimes(1)
|
||||
expect(generator.generateRoutes).toBeCalledWith(routes)
|
||||
expect(generator.afterGenerate).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledWith('generate:done', generator, errors)
|
||||
})
|
||||
|
||||
|
@ -4,7 +4,7 @@ import fsExtra from 'fs-extra'
|
||||
import { flatRoutes, isString, isUrl, promisifyRoute } from '@nuxt/utils'
|
||||
|
||||
import Generator from '../src/generator'
|
||||
import { createNuxt } from './__utils__'
|
||||
import { createNuxt, hookCalls } from './__utils__'
|
||||
|
||||
jest.mock('path')
|
||||
jest.mock('fs-extra')
|
||||
@ -63,8 +63,7 @@ describe('generator: initialize', () => {
|
||||
await generator.initiate()
|
||||
|
||||
expect(nuxt.ready).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledWith('generate:before', generator, { dir: generator.distPath })
|
||||
expect(hookCalls(nuxt, 'generate:before')[0]).toMatchObject([generator, { dir: generator.distPath }])
|
||||
expect(builder.forGenerate).toBeCalledTimes(1)
|
||||
expect(builder.build).toBeCalledTimes(1)
|
||||
expect(generator.initDist).toBeCalledTimes(1)
|
||||
@ -82,8 +81,7 @@ describe('generator: initialize', () => {
|
||||
await generator.initiate({ build: false, init: false })
|
||||
|
||||
expect(nuxt.ready).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledWith('generate:before', generator, { dir: generator.distPath })
|
||||
expect(hookCalls(nuxt, 'generate:before')[0]).toMatchObject([generator, { dir: generator.distPath }])
|
||||
expect(builder.forGenerate).not.toBeCalled()
|
||||
expect(builder.build).not.toBeCalled()
|
||||
expect(generator.initDist).not.toBeCalled()
|
||||
@ -117,8 +115,7 @@ describe('generator: initialize', () => {
|
||||
expect(flatRoutes).toBeCalledWith(['/index', '/about', '/test'])
|
||||
expect(generator.decorateWithPayloads).toBeCalledTimes(1)
|
||||
expect(generator.decorateWithPayloads).toBeCalledWith(['/index', '/about'], ['/foo', '/foo/bar'])
|
||||
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledWith('generate:extendRoutes', 'decoratedRoutes')
|
||||
expect(hookCalls(nuxt, 'generate:extendRoutes')[0][0]).toBe('decoratedRoutes')
|
||||
expect(routes).toEqual('decoratedRoutes')
|
||||
})
|
||||
|
||||
@ -147,8 +144,7 @@ describe('generator: initialize', () => {
|
||||
expect(flatRoutes).not.toBeCalled()
|
||||
expect(generator.decorateWithPayloads).toBeCalledTimes(1)
|
||||
expect(generator.decorateWithPayloads).toBeCalledWith(['/'], [])
|
||||
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledWith('generate:extendRoutes', 'decoratedRoutes')
|
||||
expect(hookCalls(nuxt, 'generate:extendRoutes')[0][0]).toBe('decoratedRoutes')
|
||||
expect(routes).toEqual('decoratedRoutes')
|
||||
|
||||
promisifyRoute.mockReset()
|
||||
@ -184,8 +180,7 @@ describe('generator: initialize', () => {
|
||||
|
||||
expect(fsExtra.emptyDir).toBeCalledTimes(1)
|
||||
expect(fsExtra.emptyDir).toBeCalledWith(generator.distPath)
|
||||
expect(nuxt.callHook).toBeCalledTimes(2)
|
||||
expect(nuxt.callHook).nthCalledWith(1, 'generate:distRemoved', generator)
|
||||
expect(hookCalls(nuxt, 'generate:distRemoved')[0][0]).toMatchObject(generator)
|
||||
expect(fsExtra.exists).toBeCalledTimes(1)
|
||||
expect(fsExtra.exists).toBeCalledWith(generator.staticRoutes)
|
||||
expect(fsExtra.copy).toBeCalledTimes(1)
|
||||
@ -194,7 +189,7 @@ describe('generator: initialize', () => {
|
||||
expect(path.resolve).toBeCalledWith(generator.distPath, '.nojekyll')
|
||||
expect(fsExtra.writeFile).toBeCalledTimes(1)
|
||||
expect(fsExtra.writeFile).toBeCalledWith(`resolve(${generator.distPath}, .nojekyll)`, '')
|
||||
expect(nuxt.callHook).nthCalledWith(2, 'generate:distCopied', generator)
|
||||
expect(hookCalls(nuxt, 'generate:distCopied')[0][0]).toMatchObject(generator)
|
||||
})
|
||||
|
||||
test('should copy static routes if path exists', async () => {
|
||||
|
@ -4,7 +4,7 @@ import fsExtra from 'fs-extra'
|
||||
import htmlMinifier from 'html-minifier'
|
||||
|
||||
import Generator from '../src/generator'
|
||||
import { createNuxt } from './__utils__'
|
||||
import { createNuxt, hookCalls } from './__utils__'
|
||||
|
||||
jest.mock('path')
|
||||
jest.mock('fs-extra')
|
||||
@ -47,17 +47,19 @@ describe('generator: generate route', () => {
|
||||
expect(path.join).toBeCalledTimes(2)
|
||||
expect(path.join).nthCalledWith(1, '[sep]', '/foo.html')
|
||||
expect(path.join).nthCalledWith(2, generator.distPath, 'join([sep], /foo.html)')
|
||||
expect(nuxt.callHook).toBeCalledTimes(2)
|
||||
expect(nuxt.callHook).nthCalledWith(1, 'generate:page', {
|
||||
|
||||
expect(hookCalls(nuxt, 'generate:page')[0][0]).toMatchObject({
|
||||
route,
|
||||
html: 'rendered html',
|
||||
path: `join(${generator.distPath}, join([sep], /foo.html))`
|
||||
})
|
||||
expect(nuxt.callHook).nthCalledWith(2, 'generate:routeCreated', {
|
||||
|
||||
expect(hookCalls(nuxt, 'generate:routeCreated')[0][0]).toMatchObject({
|
||||
route,
|
||||
errors: [],
|
||||
path: `join(${generator.distPath}, join([sep], /foo.html))`
|
||||
})
|
||||
|
||||
expect(fsExtra.mkdirp).toBeCalledTimes(1)
|
||||
expect(fsExtra.mkdirp).toBeCalledWith(`dirname(join(${generator.distPath}, join([sep], /foo.html)))`)
|
||||
expect(fsExtra.writeFile).toBeCalledTimes(1)
|
||||
@ -82,7 +84,6 @@ describe('generator: generate route', () => {
|
||||
|
||||
expect(nuxt.server.renderRoute).toBeCalledTimes(1)
|
||||
expect(nuxt.server.renderRoute).toBeCalledWith('/foo', { payload })
|
||||
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||
expect(nuxt.callHook).toBeCalledWith('generate:routeFailed', {
|
||||
route,
|
||||
errors: [{ type: 'unhandled', route, error }]
|
||||
|
17
test/fixtures/full-static/nuxt.config.js
vendored
17
test/fixtures/full-static/nuxt.config.js
vendored
@ -1,3 +1,18 @@
|
||||
export default {
|
||||
target: 'static'
|
||||
target: 'static',
|
||||
export: {
|
||||
payload: {
|
||||
config: true
|
||||
}
|
||||
},
|
||||
hooks: {
|
||||
export: {
|
||||
before ({ setPayload }) {
|
||||
setPayload({ shared: true })
|
||||
},
|
||||
route ({ route, setPayload }) {
|
||||
setPayload({ myRoute: route })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
test/fixtures/full-static/pages/payload.vue
vendored
Normal file
13
test/fixtures/full-static/pages/payload.vue
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<template>
|
||||
<div v-text="JSON.stringify(payload)" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
asyncData ({ payload }) {
|
||||
return {
|
||||
payload
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user