Closed MSkred closed 5 years ago
Hi. There is something wrong with your entry-point. When the instance is waking up and during initialization, nuxt is unable to handle requests. You have to await on nuxt.ready()
before rendering.
If you need further assistance, please provide custom server.js
This is my server.js file after npm run deploy
@pi0
import { stringify } from 'querystring'
import Vue from 'vue'
import fetch from 'node-fetch'
import middleware from './middleware.js'
import { applyAsyncData, getMatchedComponents, middlewareSeries, promisify, urlJoin, sanitizeComponent } from './utils.js'
import { createApp, NuxtError } from './index.js'
import NuxtLink from './components/nuxt-link.server.js' // should be included after ./index.js
// Component: <NuxtLink>
Vue.component(NuxtLink.name, NuxtLink)
Vue.component('NLink', NuxtLink)
if (!global.fetch) { global.fetch = fetch }
const noopApp = () => new Vue({ render: h => h('div') })
const createNext = ssrContext => (opts) => {
ssrContext.redirected = opts
// If nuxt generate
if (!ssrContext.res) {
ssrContext.nuxt.serverRendered = false
return
}
opts.query = stringify(opts.query)
opts.path = opts.path + (opts.query ? '?' + opts.query : '')
const routerBase = '/'
if (!opts.path.startsWith('http') && (routerBase !== '/' && !opts.path.startsWith(routerBase))) {
opts.path = urlJoin(routerBase, opts.path)
}
// Avoid loop redirect
if (opts.path === ssrContext.url) {
ssrContext.redirected = false
return
}
ssrContext.res.writeHead(opts.status, {
'Location': opts.path
})
ssrContext.res.end()
}
// This exported function will be called by `bundleRenderer`.
// This is where we perform data-prefetching to determine the
// state of our application before actually rendering it.
// Since data fetching is async, this function is expected to
// return a Promise that resolves to the app instance.
export default async (ssrContext) => {
// Create ssrContext.next for simulate next() of beforeEach() when wanted to redirect
ssrContext.redirected = false
ssrContext.next = createNext(ssrContext)
// Used for beforeNuxtRender({ Components, nuxtState })
ssrContext.beforeRenderFns = []
// Nuxt object (window{{globals.context}}, defaults to window.__NUXT__)
ssrContext.nuxt = { layout: 'default', data: [], error: null, state: null, serverRendered: true }
// Create the app definition and the instance (created for each request)
const { app, router, store } = await createApp(ssrContext)
const _app = new Vue(app)
// Add meta infos (used in renderer.js)
ssrContext.meta = _app.$meta()
// Keep asyncData for each matched component in ssrContext (used in app/utils.js via this.$ssrContext)
ssrContext.asyncData = {}
const beforeRender = async () => {
// Call beforeNuxtRender() methods
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
ssrContext.rendered = () => {
// Add the state from the vuex store
ssrContext.nuxt.state = store.state
}
}
const renderErrorPage = async () => {
// Load layout for error page
const errLayout = (typeof NuxtError.layout === 'function' ? NuxtError.layout(app.context) : NuxtError.layout)
ssrContext.nuxt.layout = errLayout || 'default'
await _app.loadLayout(errLayout)
_app.setLayout(errLayout)
await beforeRender()
return _app
}
const render404Page = () => {
app.context.error({ statusCode: 404, path: ssrContext.url, message: `This page could not be found` })
return renderErrorPage()
}
// Components are already resolved by setContext -> getRouteData (app/utils.js)
const Components = getMatchedComponents(router.match(ssrContext.url))
/*
** Dispatch store nuxtServerInit
*/
if (store._actions && store._actions.nuxtServerInit) {
try {
await store.dispatch('nuxtServerInit', app.context)
} catch (err) {
console.debug('Error occurred when calling nuxtServerInit: ', err.message)
throw err
}
}
// ...If there is a redirect or an error, stop the process
if (ssrContext.redirected) return noopApp()
if (ssrContext.nuxt.error) return renderErrorPage()
/*
** Call global middleware (nuxt.config.js)
*/
let midd = ["isLoggedIn"]
midd = midd.map((name) => {
if (typeof name === 'function') return name
if (typeof middleware[name] !== 'function') {
app.context.error({ statusCode: 500, message: 'Unknown middleware ' + name })
}
return middleware[name]
})
await middlewareSeries(midd, app.context)
// ...If there is a redirect or an error, stop the process
if (ssrContext.redirected) return noopApp()
if (ssrContext.nuxt.error) return renderErrorPage()
/*
** Set layout
*/
let layout = Components.length ? Components[0].options.layout : NuxtError.layout
if (typeof layout === 'function') layout = layout(app.context)
await _app.loadLayout(layout)
if (ssrContext.nuxt.error) return renderErrorPage()
layout = _app.setLayout(layout)
ssrContext.nuxt.layout = _app.layoutName
/*
** Call middleware (layout + pages)
*/
midd = []
layout = sanitizeComponent(layout)
if (layout.options.middleware) midd = midd.concat(layout.options.middleware)
Components.forEach((Component) => {
if (Component.options.middleware) {
midd = midd.concat(Component.options.middleware)
}
})
midd = midd.map((name) => {
if (typeof name === 'function') return name
if (typeof middleware[name] !== 'function') {
app.context.error({ statusCode: 500, message: 'Unknown middleware ' + name })
}
return middleware[name]
})
await middlewareSeries(midd, app.context)
// ...If there is a redirect or an error, stop the process
if (ssrContext.redirected) return noopApp()
if (ssrContext.nuxt.error) return renderErrorPage()
/*
** Call .validate()
*/
let isValid = true
try {
for (const Component of Components) {
if (typeof Component.options.validate !== 'function') {
continue
}
isValid = await Component.options.validate(app.context)
if (!isValid) {
break
}
}
} catch (validationError) {
// ...If .validate() threw an error
app.context.error({
statusCode: validationError.statusCode || '500',
message: validationError.message
})
return renderErrorPage()
}
// ...If .validate() returned false
if (!isValid) {
// Don't server-render the page in generate mode
if (ssrContext._generate) ssrContext.nuxt.serverRendered = false
// Render a 404 error page
return render404Page()
}
// If no Components found, returns 404
if (!Components.length) return render404Page()
// Call asyncData & fetch hooks on components matched by the route.
const asyncDatas = await Promise.all(Components.map((Component) => {
const promises = []
// Call asyncData(context)
if (Component.options.asyncData && typeof Component.options.asyncData === 'function') {
const promise = promisify(Component.options.asyncData, app.context)
promise.then((asyncDataResult) => {
ssrContext.asyncData[Component.cid] = asyncDataResult
applyAsyncData(Component)
return asyncDataResult
})
promises.push(promise)
} else {
promises.push(null)
}
// Call fetch(context)
if (Component.options.fetch) {
promises.push(Component.options.fetch(app.context))
} else {
promises.push(null)
}
return Promise.all(promises)
}))
// datas are the first row of each
ssrContext.nuxt.data = asyncDatas.map(r => r[0] || {})
// ...If there is a redirect or an error, stop the process
if (ssrContext.redirected) return noopApp()
if (ssrContext.nuxt.error) return renderErrorPage()
// Call beforeNuxtRender methods & add store state
await beforeRender()
return _app
}
@MSkred This is the auto-generated file. I mean lambda entry-point.
serverless.yml
service: lgc-ssr-nuxt
app: serverless-side-rendering-nuxt-app
org: maximescibetta
provider:
name: aws
runtime: nodejs8.10
stage: ${self:custom.secrets.NODE_ENV}
region: eu-west-1
environment:
NODE_ENV: ${self:custom.secrets.NODE_ENV}
functions:
nuxt:
handler: index.nuxt
events:
- http: ANY /
- http: ANY /{proxy+}
plugins:
- serverless-apigw-binary
- serverless-domain-manager
custom:
secrets: ${file(secrets.json)}
apigwBinary:
types:
- '*/*'
customDomain:
domainName: ${self:custom.secrets.DOMAIN}
basePath: ''
stage: ${self:custom.secrets.NODE_ENV}
createRoute53Record: true
nuxt.js
const express = require('express')
const app = express()
const { Nuxt } = require('nuxt')
const path = require('path')
app.use('/_nuxt', express.static(path.join(__dirname, '.nuxt', 'dist')))
const config = require('./nuxt.config.js')
const nuxt = new Nuxt(config)
app.use(nuxt.render)
module.exports = app
index.js
const sls = require('serverless-http')
const binaryMimeTypes = require('./binaryMimeTypes')
const nuxt = require('./nuxt')
module.exports.nuxt = sls(nuxt, {
binary: binaryMimeTypes
})
You need something else ? I'm sure that's what you wanted
This is my terminal result @pi0
npm run deploy
> lgc-account-pwa@1.0.0 deploy /Users/lgc/Documents/LetsGoCity/PWA/lgc-account-pwa
> nuxt build && sls deploy
WARN devModules has been renamed to buildModules and will be removed in Nuxt 3. 19:39:12
ℹ Production build 19:39:14
✔ Builder initialized 19:39:14
✔ Nuxt files generated 19:39:14
✔ Client
Compiled successfully in 11.54s
✔ Server
Compiled successfully in 3.20s
Hash: 09602a36e70873c52310
Version: webpack 4.39.2
Time: 11538ms
Built at: 2019-08-21 19:39:28
Asset Size Chunks Chunk Names
../server/client.manifest.json 12.6 KiB [emitted]
08b8fc8f46b5562e8732.js 5.85 KiB 11 [emitted] pages/motdepasseoublie/index
2469a8ca9782532115db.js 6.78 KiB 10 [emitted] pages/inscription
246bf196a6911959fb3c.js 4.27 KiB 16 [emitted]
2a0e850a01ef1c1564d6.js 5.11 KiB 9 [emitted] pages/information/preference
2b39ecb496621aeec207.js 1.02 KiB 13 [emitted] pages/motdepasseoublie/redirection
351777d51002621f5799.js 2.6 KiB 14 [emitted] runtime
8d448d8d35a2678a964d.js 78.7 KiB 2 [emitted] app
9250c72a11d50c8c748d.js 9.91 KiB 8 [emitted] pages/information/modification
96381bb7067c767fe0df.js 12.2 KiB 4 [emitted] commons.pages/inscription
LICENSES 1.16 KiB [emitted]
a4477b96903e4364654b.js 96.4 KiB 1 [emitted] vendors.pages/information/modification.pages/inscription
a4aa36c2b000f162d0a3.js 29.1 KiB 0 [emitted] pages/information/modification.pages/inscription
a8e0a6fc3e45212086cf.js 12.9 KiB 6 [emitted] pages/index
b8c4518978f6db7a5d06.js 11.3 KiB 12 [emitted] pages/motdepasseoublie/modification
c739ca8b953d66601566.js 3.5 KiB 5 [emitted] pages/autorisation
cfd2904c44941e6cb913.js 32.7 KiB 15 [emitted] vendors.app
dcb2372377826391b267.js 4.64 KiB 7 [emitted] pages/information/index
f5dcccbeac0df41cbc83.js 175 KiB 3 [emitted] commons.app
icons/icon_120.8d8a54.png 8.51 KiB [emitted]
icons/icon_144.8d8a54.png 11.1 KiB [emitted]
icons/icon_152.8d8a54.png 11.8 KiB [emitted]
icons/icon_192.8d8a54.png 16.2 KiB [emitted]
icons/icon_384.8d8a54.png 42.8 KiB [emitted]
icons/icon_512.8d8a54.png 59.6 KiB [emitted]
icons/icon_64.8d8a54.png 3.91 KiB [emitted]
manifest.66e615c0.json 816 bytes [emitted]
+ 2 hidden assets
Entrypoint app = 351777d51002621f5799.js f5dcccbeac0df41cbc83.js cfd2904c44941e6cb913.js 8d448d8d35a2678a964d.js
Hash: 275a3c7c6e5cfd468a75
Version: webpack 4.39.2
Time: 3201ms
Built at: 2019-08-21 19:39:31
Asset Size Chunks Chunk Names
3caeab9d39523e09c618.js 3.22 KiB 3 [emitted] pages/information/index
4db86521b8f9fc02a017.js 4.96 KiB 7 [emitted] pages/motdepasseoublie/index
512a084e313f6e9a6cd2.js 3.13 KiB 5 [emitted] pages/information/preference
5b379aa6d079076c0b3d.js 2.34 KiB 1 [emitted] pages/autorisation
6244a906bb81b1e222f1.js 30.8 KiB 6 [emitted] pages/inscription
640c72c2ff6e065c58b0.js 33.6 KiB 4 [emitted] pages/information/modification
9ab87bb8d40ccdd1574c.js 9.33 KiB 2 [emitted] pages/index
fdc4398f9767e768618e.js 7.88 KiB 8 [emitted] pages/motdepasseoublie/modification
fee8114a961ae65e97b4.js 983 bytes 9 [emitted] pages/motdepasseoublie/redirection
server.js 59.4 KiB 0 [emitted] app
server.manifest.json 1.17 KiB [emitted]
+ 10 hidden assets
Entrypoint app = server.js server.js.map
Serverless: An updated version of Serverless Enterprise is available. Please upgrade by running `npm i -g serverless`
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service lgc-ssr-nuxt.zip file to S3 (44.97 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............
Serverless: Stack update finished...
Service Information
service: lgc-ssr-nuxt
stage: dev
region: eu-west-1
stack: lgc-ssr-nuxt-dev
resources: 17
api keys:
None
endpoints:
ANY - https://w5civxdhfb.execute-api.eu-west-1.amazonaws.com/dev
ANY - https://w5civxdhfb.execute-api.eu-west-1.amazonaws.com/dev/{proxy+}
functions:
nuxt: lgc-ssr-nuxt-dev-nuxt
layers:
None
Serverless: Updated basepath mapping.
Serverless Domain Manager Summary
Domain Name
compte.letsgocity.be
Distribution Domain Name
Target Domain: d1quusiyn1twou.cloudfront.net
Hosted Zone Id: XXXXXXXXXX
Serverless: Removing old service artifacts from S3...
Serverless: Publishing service to the Serverless Dashboard...
Serverless: Successfully published your service to the Serverless Dashboard: https://dashboard.serverless.com/tenants/maximescibetta/applications/serverless-side-rendering-nuxt-app/services/lgc-ssr-nuxt/stage/dev/region/eu-west-1
I've 404 error sometime on some domain/dev/_nuxt/some_file.js
@pi0
Issue solved : https://cmty.app/nuxt/nuxt.js/issues/c8955
I've updated my nuxt.js
and index.js
nuxt.js
const express = require('express');
const { Nuxt } = require('nuxt');
const path = require('path');
const config = require('./nuxt.config.js');
async function start() {
const app = express();
const nuxt = new Nuxt(config);
await nuxt.ready();
app.use('/_nuxt', express.static(path.join(__dirname, '.nuxt', 'dist')));
app.use(nuxt.render);
return app;
}
module.exports = start;
index.js
const sls = require('serverless-http')
const binaryMimeTypes = require('./binaryMimeTypes')
const nuxt = require('./nuxt')
module.exports.nuxt = (evt, ctx, callback) => {
return nuxt()
.then(app =>
sls(app, {
binary: binaryMimeTypes,
})
)
.then(proxy => proxy(evt, ctx, callback))
.catch(err => console.error(err));
};
@pi0 All works very fine, but between before nuxt.ready() and after we've 7 SECONDS of delay … and my website is not showed during this time.
Hey @MSkred. It must be with some modules takes long time. Can you please share nuxt.config in a new question issue regarding slow startup?
nuxt.js
const express = require('express') const app = express() const { Nuxt } = require('nuxt') const path = require('path') app.use('/_nuxt', express.static(path.join(__dirname, '.nuxt', 'dist'))) const config = require('./nuxt.config.js') const nuxt = new Nuxt(config) app.use(nuxt.render) module.exports = app
index.js
const sls = require('serverless-http') const binaryMimeTypes = require('./binaryMimeTypes') const nuxt = require('./nuxt') module.exports.nuxt = sls(nuxt, { binary: binaryMimeTypes })
You need something else ? I'm sure that's what you wanted
replace app.use(nuxt.render) to app.use(async (req, res) => { if (nuxt.ready) { await nuxt.ready() } nuxt.render(req, res) });
nuxt.js
const express = require('express') const app = express() const { Nuxt } = require('nuxt') const path = require('path') app.use('/_nuxt', express.static(path.join(__dirname, '.nuxt', 'dist'))) const config = require('./nuxt.config.js') const nuxt = new Nuxt(config) app.use(nuxt.render) module.exports = app
index.js
const sls = require('serverless-http') const binaryMimeTypes = require('./binaryMimeTypes') const nuxt = require('./nuxt') module.exports.nuxt = sls(nuxt, { binary: binaryMimeTypes })
You need something else ? I'm sure that's what you wanted
replace app.use(nuxt.render) to app.use(async (req, res) => { if (nuxt.ready) { await nuxt.ready() } nuxt.render(req, res) });
This should be the prefered answer, tested in 2022 and this worked wonderfully I have not yet had the issue. thanks @samchong1104
Version
v2.0.0
Reproduction link
https://compte.letsgocity.be
Steps to reproduce
I've an app nuxt universal deploy on aws with lambda and when I come for the first time each 30 minutes I've an error Cannot GET /
Someone can help me ? @pi0
What is expected ?
I've an app nuxt universal deploy on aws with lambda and when I come for the first time each 30 minutes I've an error Cannot GET /
Someone can help me ? @pi0
What is actually happening?
I've an app nuxt universal deploy on aws with lambda and when I come for the first time each 30 minutes I've an error Cannot GET /
Someone can help me ? @pi0