├── .env.development ├── .env.production ├── .gitignore ├── README.md ├── app.js ├── nuxt.config.js ├── package.json ├── server.js ├── serverless.js ├── serverless.yml ├── src ├── api │ └── index.js ├── layouts │ └── default.ts ├── pages │ ├── index.ts │ ├── nuxt.ts │ └── typescript.ts ├── services │ ├── common │ │ └── layouts │ │ │ └── default.vue │ └── home │ │ └── pages │ │ ├── index.vue │ │ ├── nuxt.vue │ │ └── typescript.vue ├── store │ └── index.ts └── types │ ├── images.d.ts │ ├── nuxt.d.ts │ └── vue.shims.d.ts ├── static └── favicon.png ├── tsconfig.json ├── tslint.json ├── webpack.config.js └── yarn.lock /.env.development: -------------------------------------------------------------------------------- 1 | NUXT_APP_STAGE = "development" 2 | NUXT_APP_GRAPHQL_ENDPOINT = "https://graphql-pokemon.now.sh/" 3 | NUXT_APP_VERSION = "0.0.1" 4 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | NUXT_APP_STAGE = "production" 2 | NUXT_APP_GRAPHQL_ENDPOINT = "https://graphql-pokemon.now.sh/" 3 | NUXT_APP_VERSION = "0.0.1" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | .nuxt 61 | dist 62 | 63 | .DS_Store 64 | .serverless 65 | 66 | .env.development 67 | .env.production 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Nuxt.js SSR on AWS Serverless Stack (Lambda + API Gateway + S3) 2 | 3 | Nuxt.js Serverless Server-side Rendering Starter on AWS Serverless Stack (Lambda + API Gateway + S3) with *Serverless Framework* 4 | 5 | ### Pre-Installed 6 | - Nuxt.js 2.8.1 7 | - Serverless Framework 8 | - TypeScript 9 | - Sass (SCSS) 10 | - TSLint 11 | 12 | If you have a feature request, please create a new issue. And also, pull requests are always welcome🙏 13 | 14 | ### Caution 15 | - Libraries that are used in the client should be included in the `devDependencies` for Bundle size optimization. (because of Lambda Limit) 16 | - If you install a `module` for nuxt.js, it must be in a the `dependencies` not `devDependencies` 17 | - Auto generated URL `https://*.execute-api.{region}.amazonaws.com/{stage}/` will result in a JavaScript error. (routing problem) **Please use the Custom Domain.** 18 | - If you encounter `Cannot GET /` error message, the error log can be founded in the AWS CloudWatch. 19 | 20 | ## Pre-requisites 21 | - 🔑 **IAM Account** for *Serverless framework* (Requires pre-configuration using `aws configure`) 22 | 23 | ```bash 24 | $ aws configure 25 | ``` 26 | 27 | ## Configuration 28 | Edit `serverless.yml` 29 | 30 | ```yaml 31 | service: nuxt-serverless # 1. Edit whole service name 32 | 33 | plugins: 34 | - serverless-s3-sync 35 | - serverless-apigw-binary 36 | - serverless-dotenv-plugin 37 | 38 | package: 39 | individually: true 40 | excludeDevDependencies: true 41 | 42 | provider: 43 | name: aws 44 | runtime: nodejs10.x 45 | stage: ${opt:stage, 'dev'} 46 | region: us-east-1 # 2. Edit AWS region name 47 | 48 | custom: 49 | ####################################### 50 | # Unique ID included in resource names. 51 | # Replace it with a random value for every first distribution. 52 | # https://www.random.org/strings/?num=1&len=6&digits=on&loweralpha=on&unique=on&format=html&rnd=new 53 | stackId: abcdef # 3. Update Random Stack ID 54 | ####################################### 55 | 56 | buckets: 57 | ASSETS_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-assets 58 | STATIC_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-static 59 | s3Sync: 60 | - bucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME} 61 | localDir: .nuxt/dist/client 62 | - bucketName: ${self:custom.buckets.STATIC_BUCKET_NAME} 63 | localDir: static 64 | apigwBinary: 65 | types: 66 | - '*/*' 67 | ``` 68 | 69 | ## Build Setup 70 | ```bash 71 | # Install dependencies 72 | $ yarn 73 | 74 | # Serve develop server at localhost:3000 using Nuxt.js 75 | $ yarn dev 76 | 77 | # Build 78 | $ yarn build 79 | 80 | # Prod server start with built assets 81 | $ yarn start 82 | 83 | ## SERVERLESS DEPLOYMENT ## 84 | # Build and deploy the function and bundled assets 85 | $ yarn deploy:dev 86 | $ yarn deploy:stage 87 | $ yarn deploy:prod 88 | 89 | # Remove Deployment 90 | $ yarn undeploy:dev 91 | $ yarn undeploy:stage 92 | $ yarn undeploy:prod 93 | ``` 94 | 95 | ## Environment Variables 96 | - update `.env.development`, `.env.production`. 97 | - If env variable key started with `NUXT_APP`, it injected to client in `this.$store.state.environments`. 98 | - WARNING!: Untrack the `.env.development` and the `.env.production` before commit 99 | 100 | ## Folder Structure 101 | - `/api`: You can create a sub-API based on Express.js. dynamic ajax Set-Cookie is mainly used. 102 | > Let the URL be a `* .json` to distinguish it from the REST API that returns JSON. 103 | - `/pages`: File-based page routing. All ts files in `/pages` are only alias with `export {default}` to `/services/${serviceName}/pages/**`. all implementations should be done inside `/services`. 104 | 105 | ```typescript 106 | export { default } from '~/services/home/pages/index' 107 | ``` 108 | - `/services`: The application is divided into several services and should be implemented in a folder named by service name. (Example: `/home`, `/auth`, ...) 109 | - Inside a Service: `/components`, `/queries`, `/pages`, `/helpers`, `/types`, ... 110 | - `/store`: One Store that is globally used. 111 | - `/types`: Declare only `.d.ts`. The type used for each service should be stored in `/types' in each service. 112 | 113 | ## To-do 114 | - [x] optimize the lambda capacity (create SSR bundle with no dependencies) 115 | - [x] static file serve 116 | - [ ] gzip Compression 117 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const asyncify = require('express-asyncify') 3 | const { Nuxt } = require('nuxt') 4 | 5 | const nuxtConfig = require('./nuxt.config') 6 | const api = require('./src/api') 7 | 8 | const IS_PROD = process.env.NODE_ENV === 'production' 9 | 10 | const nuxt = new Nuxt({ 11 | ...nuxtConfig, 12 | dev: !IS_PROD, 13 | }) 14 | 15 | let isNuxtReady = false 16 | 17 | const app = asyncify(express()) 18 | 19 | app.use('/static', express.static('./static')) 20 | 21 | app.use(api) 22 | app.use(async (req, res) => (isNuxtReady || await nuxt.ready() && (isNuxtReady = true)) && nuxt.render(req, res)) 23 | 24 | module.exports = { 25 | app, 26 | nuxt, 27 | } 28 | -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | const bodyParser = require('body-parser') 2 | const cookieParser = require('cookie-parser') 3 | 4 | module.exports = { 5 | head: { 6 | title: 'nuxt-serverless', 7 | meta: [ 8 | { chatset: 'utf-8' }, 9 | { name: 'viewport', content: 'width=device-width, initial-scale=1' }, 10 | ], 11 | link: [ 12 | { rel: 'shortcut icon', type: 'image/png', href: '/static/favicon.png' }, 13 | ], 14 | }, 15 | srcDir: './src', 16 | serverMiddleware: [ 17 | bodyParser.json(), 18 | bodyParser.urlencoded({ extended: true }), 19 | cookieParser(), 20 | ], 21 | build: { 22 | standalone: true, 23 | }, 24 | render: { 25 | etag: false, 26 | compressor: { threshold: Infinity }, 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nuxt-serverless", 3 | "version": "1.0.0", 4 | "private": false, 5 | "repository": "https://github.com/tonyfromundefined/nuxt-serverless", 6 | "license": "MIT", 7 | "author": "tonyfromundefined ", 8 | "main": "index.js", 9 | "scripts": { 10 | "dev": "node ./server.js", 11 | "build": "NODE_ENV=production nuxt build", 12 | "postbuild": "webpack", 13 | "start": "NODE_ENV=production node ./.nuxt/dist/server.js", 14 | "deploy:dev": "sls deploy --stage dev", 15 | "deploy:stage": "NODE_ENV=production sls deploy --stage stage", 16 | "deploy:prod": "NODE_ENV=production sls deploy --stage prod", 17 | "undeploy:dev": "sls remove --stage dev", 18 | "undeploy:stage": "NODE_ENV=production sls remove --stage stage", 19 | "undeploy:prod": "NODE_ENV=production sls remove --stage prod" 20 | }, 21 | "dependencies": { 22 | "nuxt": "^2.8.1" 23 | }, 24 | "devDependencies": { 25 | "@nuxt/typescript": "^2.8.1", 26 | "@types/aws-serverless-express": "^3.3.1", 27 | "@types/cookie-parser": "^1.4.1", 28 | "aws-serverless-express": "^3.3.6", 29 | "body-parser": "^1.19.0", 30 | "cookie-parser": "^1.4.4", 31 | "dotenv": "^8.0.0", 32 | "express": "^4.17.1", 33 | "express-asyncify": "^1.0.0", 34 | "lodash": "^4.17.13", 35 | "node-sass": "^4.12.0", 36 | "nuxt-property-decorator": "^2.3.0", 37 | "sass-loader": "^7.1.0", 38 | "serverless": "^1.45.1", 39 | "serverless-apigw-binary": "^0.4.4", 40 | "serverless-dotenv-plugin": "^2.1.1", 41 | "serverless-s3-sync": "^1.8.0", 42 | "ts-node": "^8.2.0", 43 | "tslint": "^5.17.0", 44 | "typescript": "^3.5.1", 45 | "vue": "^2.6.10", 46 | "vue-class-component": "^7.1.0", 47 | "vuex": "^3.1.1", 48 | "vuex-class": "^0.3.2", 49 | "webpack": "^4.33.0", 50 | "webpack-cli": "^3.3.4", 51 | "webpackbar": "^3.2.0" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const { Builder } = require('nuxt') 2 | const { app, nuxt } = require('./app') 3 | 4 | const IS_PROD = process.env.NODE_ENV === 'production' 5 | const PORT = IS_PROD ? 80 : 3000 6 | 7 | require('dotenv').config({ 8 | path: `./.env.${IS_PROD ? 'production' : 'development'}`, 9 | }); 10 | 11 | (async function main() { 12 | if (!IS_PROD) { 13 | await new Builder(nuxt).build() 14 | } 15 | 16 | app.listen(PORT) 17 | })() 18 | -------------------------------------------------------------------------------- /serverless.js: -------------------------------------------------------------------------------- 1 | const awsServerlessExpress = require('aws-serverless-express') 2 | const { app } = require('./app') 3 | 4 | const BINARY_MIME_TYPES = [ 5 | 'application/javascript', 6 | 'application/json', 7 | 'application/octet-stream', 8 | 'application/xml', 9 | 'text/css', 10 | 'text/html', 11 | 'text/javascript', 12 | 'text/plain', 13 | 'text/text', 14 | 'text/xml', 15 | ] 16 | 17 | const server = awsServerlessExpress.createServer(app, null, BINARY_MIME_TYPES) 18 | exports.handler = (event, context) => awsServerlessExpress.proxy(server, event, context) 19 | -------------------------------------------------------------------------------- /serverless.yml: -------------------------------------------------------------------------------- 1 | service: nuxt-serverless 2 | 3 | plugins: 4 | - serverless-s3-sync 5 | - serverless-apigw-binary 6 | - serverless-dotenv-plugin 7 | 8 | package: 9 | individually: true 10 | excludeDevDependencies: true 11 | 12 | provider: 13 | name: aws 14 | runtime: nodejs10.x 15 | stage: ${opt:stage, 'dev'} 16 | region: us-east-1 17 | 18 | custom: 19 | ####################################### 20 | # Unique ID included in resource names. 21 | # Replace it with a random value for every first distribution. 22 | # https://www.random.org/strings/?num=1&len=6&digits=on&loweralpha=on&unique=on&format=html&rnd=new 23 | stackId: lxpmd3 24 | ####################################### 25 | 26 | buckets: 27 | ASSETS_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-assets 28 | STATIC_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-static 29 | s3Sync: 30 | - bucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME} 31 | localDir: .nuxt/dist/client 32 | - bucketName: ${self:custom.buckets.STATIC_BUCKET_NAME} 33 | localDir: static 34 | apigwBinary: 35 | types: 36 | - '*/*' 37 | 38 | functions: 39 | renderer: 40 | name: ${self:service}-${self:custom.stackId}-${self:provider.stage}-renderer 41 | handler: .nuxt/dist/serverless.handler 42 | memorySize: 2048 43 | timeout: 30 44 | environment: 45 | NODE_ENV: production 46 | package: 47 | include: 48 | - .nuxt/dist/serverless.js 49 | - .nuxt/dist/server/** 50 | exclude: 51 | - .nuxt/** 52 | - src/** 53 | - app.js 54 | - nuxt.config.js 55 | - nuxt.d.ts 56 | - README.md 57 | - server.js 58 | - serverless.js 59 | - serverless.yml 60 | - tsconfig.json 61 | - tslint.json 62 | - webpack.config.js 63 | - yarn-error.log 64 | events: 65 | - http: 66 | path: / 67 | method: any 68 | - http: 69 | path: /{proxy+} 70 | method: any 71 | - http: 72 | path: /_nuxt/{proxy+} 73 | method: any 74 | integration: http-proxy 75 | request: 76 | uri: https://${self:custom.buckets.ASSETS_BUCKET_NAME}.s3.${self:provider.region}.amazonaws.com/{proxy} 77 | parameters: 78 | paths: 79 | proxy: true 80 | - http: 81 | path: /static/{proxy+} 82 | method: any 83 | integration: http-proxy 84 | request: 85 | uri: https://${self:custom.buckets.STATIC_BUCKET_NAME}.s3.${self:provider.region}.amazonaws.com/{proxy} 86 | parameters: 87 | paths: 88 | proxy: true 89 | 90 | resources: 91 | Resources: 92 | ClientAssetsBucket: 93 | Type: AWS::S3::Bucket 94 | Properties: 95 | BucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME} 96 | CorsConfiguration: 97 | CorsRules: 98 | - 99 | AllowedOrigins: 100 | - '*' 101 | AllowedHeaders: 102 | - '*' 103 | AllowedMethods: 104 | - GET 105 | - HEAD 106 | - PUT 107 | - POST 108 | - DELETE 109 | MaxAge: 3000 110 | ExposedHeaders: 111 | - x-amz-server-side-encryption 112 | - x-amz-request-id 113 | - x-amz-id-2 114 | ClientAssetsBucketPolicy: 115 | Type: AWS::S3::BucketPolicy 116 | Properties: 117 | Bucket: 118 | Ref: ClientAssetsBucket 119 | PolicyDocument: 120 | Version: '2012-10-17' 121 | Statement: [ 122 | { 123 | Action: ['s3:GetObject'], 124 | Effect: 'Allow', 125 | Resource: { 126 | Fn::Join: ['', ['arn:aws:s3:::', { Ref: 'ClientAssetsBucket' }, '/*']], 127 | }, 128 | Principal: '*' 129 | }, 130 | ] 131 | ClientStaticBucket: 132 | Type: AWS::S3::Bucket 133 | Properties: 134 | BucketName: ${self:custom.buckets.STATIC_BUCKET_NAME} 135 | CorsConfiguration: 136 | CorsRules: 137 | - 138 | AllowedOrigins: 139 | - '*' 140 | AllowedHeaders: 141 | - '*' 142 | AllowedMethods: 143 | - GET 144 | - HEAD 145 | - PUT 146 | - POST 147 | - DELETE 148 | MaxAge: 3000 149 | ExposedHeaders: 150 | - x-amz-server-side-encryption 151 | - x-amz-request-id 152 | - x-amz-id-2 153 | ClientStaticBucketPolicy: 154 | Type: AWS::S3::BucketPolicy 155 | Properties: 156 | Bucket: 157 | Ref: ClientStaticBucket 158 | PolicyDocument: 159 | Version: '2012-10-17' 160 | Statement: [ 161 | { 162 | Action: ['s3:GetObject'], 163 | Effect: 'Allow', 164 | Resource: { 165 | Fn::Join: ['', ['arn:aws:s3:::', { Ref: 'ClientStaticBucket' }, '/*']], 166 | }, 167 | Principal: '*' 168 | }, 169 | ] 170 | -------------------------------------------------------------------------------- /src/api/index.js: -------------------------------------------------------------------------------- 1 | const { Router } = require('express') 2 | 3 | const router = Router() 4 | 5 | /** 6 | * @todo 7 | * APIs can be implemented using express.js 8 | */ 9 | 10 | router.get('/index.json', (_req, res) => { 11 | return res.json({ 12 | hello: 'world', 13 | }) 14 | }) 15 | 16 | module.exports = router 17 | -------------------------------------------------------------------------------- /src/layouts/default.ts: -------------------------------------------------------------------------------- 1 | export { default } from '~/services/common/layouts/default.vue' 2 | -------------------------------------------------------------------------------- /src/pages/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Implementation of page is in `/services` 3 | * I've separated the code with service module for future scalability. 4 | * Separate common elements used in page implementations such as `/queries`, `/helpers`, `/components` by service name 5 | * https://softwareengineering.stackexchange.com/questions/338597/folder-by-type-or-folder-by-feature 6 | */ 7 | 8 | export { default } from '../services/home/pages/index.vue' 9 | -------------------------------------------------------------------------------- /src/pages/nuxt.ts: -------------------------------------------------------------------------------- 1 | export { default } from '~/services/home/pages/nuxt.vue' 2 | -------------------------------------------------------------------------------- /src/pages/typescript.ts: -------------------------------------------------------------------------------- 1 | export { default } from '~/services/home/pages/typescript.vue' 2 | -------------------------------------------------------------------------------- /src/services/common/layouts/default.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/services/home/pages/index.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 38 | 39 | 46 | -------------------------------------------------------------------------------- /src/services/home/pages/nuxt.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 22 | -------------------------------------------------------------------------------- /src/services/home/pages/typescript.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import pickBy from 'lodash/pickBy' 2 | import { ActionTree, MutationTree } from 'vuex' 3 | 4 | export interface IEnvironments { 5 | [key: string]: string | undefined 6 | } 7 | 8 | interface IState { 9 | environments: IEnvironments 10 | } 11 | export function state(): IState { 12 | return { 13 | environments: {}, 14 | } 15 | } 16 | 17 | export const mutations: MutationTree = { 18 | setEnvironment(state, environments: IEnvironments) { 19 | state.environments = environments 20 | }, 21 | } 22 | 23 | export const actions: ActionTree = { 24 | async nuxtServerInit({ commit }) { 25 | commit('setEnvironment', extractNuxtEnvironments(process.env)) 26 | }, 27 | } 28 | 29 | function extractNuxtEnvironments(environments: IEnvironments): IEnvironments { 30 | return pickBy(environments, (_value, key) => key.indexOf('NUXT_APP') !== -1) 31 | } 32 | -------------------------------------------------------------------------------- /src/types/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.jpg' { 2 | const url: string 3 | export default url 4 | } 5 | 6 | declare module '*.svg' { 7 | const url: string 8 | export default url 9 | } 10 | 11 | declare module '*.png' { 12 | const url: string 13 | export default url 14 | } 15 | -------------------------------------------------------------------------------- /src/types/nuxt.d.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import { Route } from 'vue-router' 3 | import { MetaInfo } from 'vue-meta' 4 | 5 | declare module 'vue/types/options' { 6 | type Context = any 7 | interface Transition { 8 | name?: string 9 | mode?: string, 10 | css?: boolean, 11 | duration?: number, 12 | type?: string, 13 | enterClass?: string, 14 | enterToClass?: string, 15 | enterActiveClass?: string, 16 | leaveClass?: string, 17 | leaveToClass?: string, 18 | leaveActiveClass?: string 19 | } 20 | 21 | interface ComponentOptions { 22 | asyncData?: (ctx: Context) => object 23 | fetch?: (ctx: Context) => Promise | void 24 | head?: MetaInfo | (() => MetaInfo) 25 | layout?: string | ((ctx: Context) => string) 26 | middleware?: string | string[] 27 | scrollToTop?: boolean 28 | transition?: string | Transition | ((to: Route, from: Route) => string) 29 | validate?: (ctx: Context) => Promise | boolean 30 | watchQuery?: boolean | string[] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/types/vue.shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import Vue from 'vue'; 3 | export default Vue; 4 | } 5 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tonyfromundefined/nuxt-serverless/638d1c27ef52051851b0a41d45f8ce7f4b3b0c35/static/favicon.png -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "target": "es6", 5 | "lib": [ 6 | "esnext", 7 | "dom", 8 | "dom.iterable", 9 | "scripthost", 10 | "esnext.asynciterable" 11 | ], 12 | "module": "es6", 13 | "moduleResolution": "node", 14 | "experimentalDecorators": true, 15 | "jsx": "preserve", 16 | "allowSyntheticDefaultImports": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "removeComments": false, 20 | "preserveConstEnums": true, 21 | "sourceMap": true, 22 | "skipLibCheck": true, 23 | "esModuleInterop": true, 24 | "strict": true, 25 | "strictNullChecks": true, 26 | "strictPropertyInitialization": false, 27 | "baseUrl": ".", 28 | "paths": { 29 | "~/*": ["./src/*"] 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "warning", 3 | "extends": [ 4 | "tslint:recommended" 5 | ], 6 | "linterOptions": { 7 | "exclude": [ 8 | "node_modules/**/*.ts", 9 | ".nuxt/**/*.js" 10 | ] 11 | }, 12 | "rules": { 13 | "semicolon": [true, "never"], 14 | "quotemark": [true, "single"], 15 | "indent": [true, "spaces", 2], 16 | "object-literal-sort-keys": false, 17 | "no-shadowed-variable": false, 18 | "max-line-length": false, 19 | "prefer-for-of": false, 20 | "variable-name": false, 21 | "no-empty": false, 22 | "jsx-boolean-value": false, 23 | "no-console": [true, "log"], 24 | "member-access": false, 25 | "max-classes-per-file": false, 26 | "jsx-no-multiline-js": false, 27 | "member-ordering": false, 28 | "no-var-requires": false 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const WebpackBarPlugin = require('webpackbar') 3 | 4 | module.exports = { 5 | mode: 'production', 6 | entry: { 7 | server: path.resolve(__dirname, './server.js'), 8 | serverless: path.resolve(__dirname, './serverless.js'), 9 | }, 10 | output: { 11 | path: path.resolve(__dirname, './.nuxt/dist'), 12 | filename: '[name].js', 13 | libraryTarget: 'commonjs', 14 | }, 15 | target: 'node', 16 | externals: [ 17 | 'nuxt', 18 | ], 19 | stats: 'errors-only', 20 | plugins: [ 21 | new WebpackBarPlugin({ 22 | name: 'Serverless', 23 | color: '#228be6', 24 | }), 25 | ], 26 | } 27 | --------------------------------------------------------------------------------