├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── api └── index.js ├── assets └── .gitkeep ├── components └── .gitkeep ├── index.js ├── layouts └── default.vue ├── middleware └── .gitkeep ├── nuxt.config.js ├── package-lock.json ├── package.json ├── pages └── index.vue ├── plugins └── .gitkeep ├── static └── img │ └── icon.png ├── store └── index.js └── vue-stack.js /.dockerignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,nuxt 3 | # Edit at https://www.gitignore.io/?templates=node,nuxt 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional REPL history 58 | .node_repl_history 59 | 60 | # Output of 'npm pack' 61 | *.tgz 62 | 63 | # Yarn Integrity file 64 | .yarn-integrity 65 | 66 | # dotenv environment variables file 67 | .env 68 | .env.test 69 | 70 | # parcel-bundler cache (https://parceljs.org/) 71 | .cache 72 | 73 | # next.js build output 74 | .next 75 | 76 | # nuxt.js build output 77 | .nuxt 78 | 79 | # vuepress build output 80 | .vuepress/dist 81 | 82 | # Serverless directories 83 | .serverless/ 84 | 85 | # FuseBox cache 86 | .fusebox/ 87 | 88 | # DynamoDB Local files 89 | .dynamodb/ 90 | 91 | ### Nuxt ### 92 | # gitignore template for Nuxt.js projects 93 | # 94 | # Recommended template: Node.gitignore 95 | 96 | # Nuxt build 97 | 98 | # Nuxt generate 99 | dist 100 | 101 | # Nuxt PWA 102 | sw.* 103 | 104 | # Git files 105 | .git 106 | .gitignore 107 | README.md 108 | 109 | # End of https://www.gitignore.io/api/node,nuxt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/node,nuxt 3 | # Edit at https://www.gitignore.io/?templates=node,nuxt 4 | 5 | ### Node ### 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | 29 | # nyc test coverage 30 | .nyc_output 31 | 32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 33 | .grunt 34 | 35 | # Bower dependency directory (https://bower.io/) 36 | bower_components 37 | 38 | # node-waf configuration 39 | .lock-wscript 40 | 41 | # Compiled binary addons (https://nodejs.org/api/addons.html) 42 | build/Release 43 | 44 | # Dependency directories 45 | node_modules/ 46 | jspm_packages/ 47 | 48 | # TypeScript v1 declaration files 49 | typings/ 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional REPL history 58 | .node_repl_history 59 | 60 | # Output of 'npm pack' 61 | *.tgz 62 | 63 | # Yarn Integrity file 64 | .yarn-integrity 65 | 66 | # dotenv environment variables file 67 | .env 68 | .env.test 69 | 70 | # parcel-bundler cache (https://parceljs.org/) 71 | .cache 72 | 73 | # next.js build output 74 | .next 75 | 76 | # nuxt.js build output 77 | .nuxt 78 | 79 | # vuepress build output 80 | .vuepress/dist 81 | 82 | # Serverless directories 83 | .serverless/ 84 | 85 | # FuseBox cache 86 | .fusebox/ 87 | 88 | # DynamoDB Local files 89 | .dynamodb/ 90 | 91 | ### Nuxt ### 92 | # gitignore template for Nuxt.js projects 93 | # 94 | # Recommended template: Node.gitignore 95 | 96 | # Nuxt build 97 | 98 | # Nuxt generate 99 | dist 100 | 101 | # Nuxt PWA 102 | sw.* 103 | 104 | # End of https://www.gitignore.io/api/node,nuxt -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | RUN apk add --update nodejs npm 3 | RUN mkdir -p /usr/src/app 4 | WORKDIR /usr/src/app 5 | COPY package*.json ./ 6 | RUN npm install --production 7 | COPY . . 8 | RUN npm run build 9 | EXPOSE 3000 10 | CMD [ "npm", "start" ] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-stack 2 | Minimalistic Boilerplate for FullStack Express and Vue.js applications with PWA support. 3 | 4 | > To understand how this boilerplate works, see the [Nuxt.js documentation](https://nuxtjs.org). 5 | 6 | ## Installation 7 | 8 | ```sh 9 | git clone https://github.com/samuelnovaes/vue-stack.git 10 | cd vue-stack 11 | npm install 12 | npm run dev 13 | ``` 14 | 15 | ## Express API (With hot reload in dev mode!) 16 | 17 | There is a `api` directory with the Express API. Each route is mapped to `/api`. 18 | > `BodyParser` is included by default. 19 | 20 | ### Example 21 | 22 | api/index.js 23 | 24 | ```javascript 25 | const router = require('express').Router() 26 | 27 | // GET /api/greeting 28 | router.get('/greeting', (req, res) => { 29 | console.log('Hello World!') 30 | }) 31 | 32 | module.exports = router 33 | ``` 34 | 35 | ## Index.js file 36 | 37 | The index.js file is responsible for starting the Express application. The `vueStack(app, port)` function starts the application on a specific port. 38 | 39 | ```javascript 40 | const express = require('express') 41 | const vueStack = require('./vue-stack') 42 | const app = express() 43 | 44 | vueStack(app, process.env.PORT || 3000) 45 | ``` 46 | 47 | The `vueStack` function returns a Promise. 48 | 49 | ## PWA 50 | 51 | By default, Vue Stack generates a PWA application en production mode. You can customize its manifest and icons in nuxt.config.js 52 | 53 | ## Commands 54 | 55 | Command | Description 56 | --- | --- 57 | npm run dev | Launch a development server on localhost:3000 with hot-reloading. 58 | npm run build | Build your application with webpack and minify the JS & CSS (for production). 59 | npm start | Start the server in production mode (after running nuxt build). 60 | npm run generate | Build the application and generate every route as a HTML file (used for static hosting). 61 | 62 | ## Using Docker 63 | 64 | ``` 65 | # docker build -t [IMAGE_NAME] . 66 | # docker run -d --name [CONTAINER_NAME] -p [PORT]:3000 [IMAGE_NAME] 67 | ``` 68 | 69 | ## See more 70 | 71 | - [Node.js](https://nodejs.org) 72 | - [ExpressJS](http://expressjs.com) 73 | - [Vue.js](http://vuejs.org) 74 | - [Nuxt.js](https://nuxtjs.org) 75 | - [Nuxt PWA](https://pwa.nuxtjs.org) -------------------------------------------------------------------------------- /api/index.js: -------------------------------------------------------------------------------- 1 | const router = require('express').Router() 2 | 3 | //Express API here 4 | 5 | module.exports = router -------------------------------------------------------------------------------- /assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuelnovaes/vue-stack/d0eb3df2b6faac247b6a35973bdc9c51cc2904cc/assets/.gitkeep -------------------------------------------------------------------------------- /components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuelnovaes/vue-stack/d0eb3df2b6faac247b6a35973bdc9c51cc2904cc/components/.gitkeep -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const vueStack = require('./vue-stack') 3 | const app = express() 4 | 5 | vueStack(app, process.env.PORT || 3000) -------------------------------------------------------------------------------- /layouts/default.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /middleware/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuelnovaes/vue-stack/d0eb3df2b6faac247b6a35973bdc9c51cc2904cc/middleware/.gitkeep -------------------------------------------------------------------------------- /nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | mode: 'spa', 3 | head: { 4 | title: 'Vue Stack', 5 | meta: [ 6 | { charset: 'utf-8' }, 7 | { name: 'viewport', content: 'width=device-width, initial-scale=1' } 8 | ], 9 | link: [ 10 | { rel: 'icon', type: 'image/png', href: '/img/icon.png' } 11 | ] 12 | }, 13 | loading: { 14 | color: '#FF0000' 15 | }, 16 | build: { 17 | extractCSS: true 18 | }, 19 | modules: [ 20 | ['@nuxtjs/pwa'] 21 | ], 22 | manifest: { 23 | name: "Vue Stack", 24 | short_name: "Vue Stack", 25 | theme_color: "#1976D2", 26 | background_color: "#1976D2", 27 | display: "standalone", 28 | orientation: "any", 29 | scope: "/", 30 | start_url: "/", 31 | description: "Minimalistic Boilerplate for FullStack Express and Vue.js applications with PWA support." 32 | }, 33 | icon: { 34 | iconSrc: 'static/img/icon.png' 35 | } 36 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-stack", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "dev": "node index.js", 6 | "build": "nuxt build", 7 | "start": "cross-env NODE_ENV=production node index.js", 8 | "generate": "nuxt generate" 9 | }, 10 | "dependencies": { 11 | "@nuxtjs/pwa": "^3.0.0-beta.14", 12 | "cross-env": "^5.2.0", 13 | "express": "^4.16.4", 14 | "nuxt": "^2.6.2" 15 | }, 16 | "devDependencies": { 17 | "chokidar": "^2.1.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /pages/index.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuelnovaes/vue-stack/d0eb3df2b6faac247b6a35973bdc9c51cc2904cc/plugins/.gitkeep -------------------------------------------------------------------------------- /static/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuelnovaes/vue-stack/d0eb3df2b6faac247b6a35973bdc9c51cc2904cc/static/img/icon.png -------------------------------------------------------------------------------- /store/index.js: -------------------------------------------------------------------------------- 1 | export const state = () => ({ 2 | 3 | }) 4 | 5 | export const mutations = { 6 | 7 | } -------------------------------------------------------------------------------- /vue-stack.js: -------------------------------------------------------------------------------- 1 | //Do not touch here! 2 | 3 | const { Nuxt, Builder } = require('nuxt') 4 | const path = require('path') 5 | const config = require('./nuxt.config.js') 6 | const express = require('express') 7 | 8 | config.dev = !(process.env.NODE_ENV === 'production') 9 | const nuxt = new Nuxt(config) 10 | 11 | const refreshAPI = () => { 12 | Object.keys(require.cache).forEach(id => { 13 | if (id.startsWith(`${path.join(__dirname, 'api')}${path.sep}`)) { 14 | delete require.cache[id] 15 | } 16 | }) 17 | } 18 | 19 | module.exports = async function (app, port) { 20 | app.use(express.json()) 21 | app.use(express.urlencoded({ extended: false })) 22 | app.use('/api', (req, res, next) => { require('./api/index.js')(req, res, next) }) 23 | app.use(nuxt.render) 24 | 25 | if (config.dev) { 26 | const chokidar = require('chokidar') 27 | const watcher = chokidar.watch(path.join(__dirname, 'api')) 28 | watcher.on('add', refreshAPI) 29 | watcher.on('change', refreshAPI) 30 | await new Builder(nuxt).build() 31 | } 32 | 33 | await nuxt.ready() 34 | app.listen(port, () => { 35 | console.log(`Server running on port ${port}`) 36 | }) 37 | } --------------------------------------------------------------------------------