8000 Serverless: add example with serverless by kamleshchandnani · Pull Request #6685 · vercel/next.js · GitHub
[go: up one dir, main page]

Skip to content

Serverless: add example with serverless #6685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion examples/with-env-from-next-config-js/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ module.exports = phase => {
const env = {
RESTURL_SPEAKERS: (() => {
if (isDev) return 'http://localhost:4000/speakers'
if (isProd) { return 'https://www.siliconvalley-codecamp.com/rest/speakers/ps' }
if (isProd) {
return 'https://www.siliconvalley-codecamp.com/rest/speakers/ps'
}
if (isStaging) return 'http://localhost:11639'
return 'RESTURL_SPEAKERS:not (isDev,isProd && !isStaging,isProd && isStaging)'
})(),
Expand Down
14 changes: 8 additions & 6 deletions examples/with-mobx-react-lite/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ function InjectStoreContext ({ children, initialData }) {
let timerInterval = null
store = useObservable(initializeData(initialData))

start = useCallback(action(() => {
timerInterval = setInterval(() => {
store.lastUpdate = Date.now()
store.light = true
}, 1000)
}))
start = useCallback(
action(() => {
timerInterval = setInterval(() => {
store.lastUpdate = Date.now()
store.light = true
}, 1000)
})
)

stop = () => {
if (timerInterval) {
Expand Down
4 changes: 4 additions & 0 deletions examples/with-serverless-framework/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": []
}
22 changes: 22 additions & 0 deletions examples/with-serverless-framework/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# with-serverless-framework
An example of nextjs with serverless

## Setup
1. Clone the repo
2. Run `npm install`

### Run local
1. Run `npm run local`
2. The project will be running at `http://localhots:8000`

### Run Serverless
1. Run `npm run development`
2. The project will be running at `http://localhots:8000`

## Goal?
The main goal of this example is to get all the following pieces work together
1. Use `serverless`
2. Use `serverless-offline` to emulate offline serverless
3. Use `express` to handle all the routes and middlewares
4. Use `aws-serverless-express`

8 changes: 8 additions & 0 deletions examples/with-serverless-framework/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"region": "do-not-deploy-local",
"vpc": {
"securityGroupIds": [],
"subnetIds": []
},
"vpce": ""
}
5 changes: 5 additions & 0 deletions examples/with-serverless-framework/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
useFileSystemPublicRoutes: false,
distDir: '.next',
target: 'serverless'
}
40 changes: 40 additions & 0 deletions examples/with-serverless-framework/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "with-serverless-framework",
"version": "1.0.0",
"description": "Rodimus next.js project",
"main": "index.js",
"dependencies": {
"aws-serverless-express": "3.3.5",
"compression": "1.7.3",
"copy-webpack-plugin": "5.0.0",
"express": "4.16.4",
"helmet": "3.15.1",
"next": "8.0.3",
"react": "16.8.3",
"react-dom": "16.8.3",
"serverless-webpack": "5.2.0",
"webpack": "4.29.6",
"webpack-node-externals": "1.7.2"
},
"devDependencies": {
"babel-loader": "8.0.5",
"concurrently": "4.1.0",
"npm-run-all": "4.1.5",
"serverless": "1.38.0",
"serverless-offline": "4.8.1",
"serverless-plugin-warmup": "4.4.3-rc.1",
"serverless-prune-plugin": "1.3.2",
"webpack-cli": "3.2.3"
},
"scripts": {
"local": "run-s local:build local:start",
"local:build": "STAGE=local webpack --config ./webpack.server.js --progress",
"local:start": "STAGE=local node ./build/server/main.js",
"development": "run-s development:build development:start",
"development:build": "STAGE=development next build",
"development:start": "STAGE=development serverless offline start --dontPrintOutput --preserveTrailingSlash"
},
"keywords": [],
"author": "",
"license": "ISC"
}
3 changes: 3 additions & 0 deletions examples/with-serverless-framework/pages/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react'

export default () => <div>Page A</div>
3 changes: 3 additions & 0 deletions examples/with-serverless-framework/pages/b.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react'

export default () => <div>Page B</div>
21 changes: 21 additions & 0 deletions examples/with-serverless-framework/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import Link from 'next/link'

const PostLink = (props) => (
<li>
<Link as={`/posts/${props.id}`} href={`/posts/${props.id}`}>
<a>{props.title}</a>
</Link>
</li>
)

export default () => (
<React.Fragment>
<h1>My Blog</h1>
<ul>
<PostLink id='hello-nextjs' title='Hello Next.js' />
<PostLink id='learn-nextjs' title='Learn Next.js is awesome' />
<PostLink id='deploy-nextjs' title='Deploy apps with Zeit' />
</ul>
</React.Fragment>
)
10 changes: 10 additions & 0 deletions examples/with-serverless-framework/pages/posts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react'
import { withRouter } from 'next/router'

const Posts = (props) => (
<div>
Page Posts {props.router.query.title}
</div>
)

export default withRouter(Posts)
61 changes: 61 additions & 0 deletions examples/with-serverless-framework/serverless.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
service:
name: with-serverless-framework

plugins:
- serverless-webpack
- serverless-offline
- serverless-prune-plugin
- serverless-plugin-warmup

custom:
webpack:
webpackConfig: webpack.server.js
includeModules:
forceExclude:
- aws-sdk
serverless-offline:
port: 8000
prune:
automatic: true
number: 5
warmup:
default: production
prewarm: true

provider:
name: aws
runtime: nodejs8.10
endpointType: private
stage: ${env:STAGE}
region: ${file(./config.json):region}
vpc: ${file(./config.json):vpc}
iamRoleStatements:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource:
- "*"
resourcePolicy:
- Effect: Allow
Principal: "*"
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
Condition:
StringEquals:
aws:sourceVpce:
- ${file(./config.json):vpce}

functions:
server:
description: with-serverless-framework server handler
handler: src/server/serverless.handler
memorySize: 128
tracing: true
events:
- http:
path: /
method: ANY
- http:
path: /{proxy+}
method: ANY
14 changes: 14 additions & 0 deletions examples/with-serverless-framework/src/app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import express from 'express'
import helmet from 'helmet'
import compression from 'compression'
// import cookieParser from 'cookie-parser';
import nextConfig from '../../next.config'

const app = express()
app.set('trust proxy', true)
app.use(helmet({ dnsPrefetchControl: false }))
app.use(compression())
app.use('/health', (req, res) => res.send({ 'with-serverless-framework': true }))
app.use('/_next', express.static(nextConfig.distDir))

export default app
16 changes: 16 additions & 0 deletions examples/with-serverless-framework/src/routes/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const routes = [{
path: '/',
page: '/index'
}, {
path: '/a',
page: '/a'
}, {
path: '/b',
page: '/b'
},
{
path: '/posts/:id',
page: '/posts'
}]

export default routes
24 changes: 24 additions & 0 deletions examples/with-serverless-framework/src/server/next.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import next from 'next'
import app from '../app/app'
import routes from '../routes/routes'

const PORT = process.env.PORT || 8000

const nextApp = next({
dev: process.env.STAGE === 'local'
})

const requestHandler = nextApp.getRequestHandler()

routes.forEach((route) => {
app.get(route.path, (req, res) => nextApp.render(req, res, route.page, { title: req.params.id }))
})

app.get('*', (req, res) => requestHandler(req, res))

nextApp.prepare().then(() => {
app.listen(PORT, (err) => {
if (err) throw err
console.log(`Project is running as ${process.env.STAGE} on port ${PORT}`)
})
})
36 changes: 36 additions & 0 deletions examples/with-serverless-framework/src/server/serverless.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import awsServerlessExpress from 'aws-serverless-express'
import app from '../app/app'
import routes from '../routes/routes'

const binaryMimeTypes = [
'application/javascript',
'application/json',
'application/octet-stream',
'application/xml',
'font/eot',
'font/opentype',
'font/otf',
'image/jpeg',
'image/png',
'image/svg+xml',
'text/comma-separated-values',
'text/css',
'text/html',
'text/javascript',
'text/plain',
'text/text',
'text/xml'
]

export const handler = (event, context) => {
routes.forEach((route) => {
/* eslint-disable import/no-dynamic-require, global-require */
app.get(route.path, (req, res) => require(`../../.next/serverless/pages${route.page}.js`).render(req, res))
/* eslint-enable import/no-dynamic-require, global-require */
})
return awsServerlessExpress.proxy(
awsServerlessExpress.createServer(app, null, binaryMimeTypes),
event,
context
)
}
53 changes: 53 additions & 0 deletions examples/with-serverless-framework/webpack.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const path = require('path')
const webpack = require('webpack')
const slsw = require('serverless-webpack')
const nodeExternals = require('webpack-node-externals')

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
mode: isProd ? 'production' : 'development',

entry:
process.env.STAGE === 'local' ? './src/server/next.js' : slsw.lib.entries,

target: 'node',

externals: [nodeExternals(), 'aws-sdk'],

output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.next/server'),
filename: '[name].js'
},

module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'next/babel',
{
'preset-env': {
modules: 'commonjs'
}
}
]
]
}
}
},
{ test: /\.mjs$/, type: 'javascript/auto', use: [] }
]
},
plugins: [
new webpack.DefinePlugin({
__STAGE__: JSON.stringify(process.env.STAGE)
})
]
}
0