* Frontend is now served by the API process
* Only 1 process spawns for lolisafe to work
* Switched frontend from server-side render to static site, now saved in `/dist`
This commit is contained in:
Pitu 2020-05-09 19:21:20 +09:00
parent d63f1f57e9
commit c114e59be3
8 changed files with 46 additions and 62 deletions

13
.gitignore vendored
View File

@ -1,21 +1,10 @@
# Packages
node_modules/
_dist/
.ream/
dist/
.nuxt/
# Log files
logs/
*.log
# Miscellaneous
.tmp/
.vscode/
# Lolisafe specifics
config.js
database.sqlite
uploads/
src/oldsite
.env
!src/api/routes/uploads

View File

@ -1,24 +1,25 @@
import dotenv from 'dotenv/config';
import autoprefixer from 'autoprefixer';
import serveStatic from 'serve-static';
import path from 'path';
import jetpack from 'fs-jetpack';
const clientConfig = {
development: process.env.NODE_ENV !== 'production',
version: process.env.npm_package_version,
URL: process.env.DOMAIN,
baseURL: `${process.env.DOMAIN}${process.env.ROUTE_PREFIX}`,
serviceName: process.env.SERVICE_NAME,
maxFileSize: process.env.MAX_SIZE,
chunkSize: process.env.CHUNK_SIZE,
maxLinksPerAlbum: process.env.MAX_LINKS_PER_ALBUM,
publicMode: process.env.PUBLIC_MODE,
userAccounts: process.env.USER_ACCOUNTS
};
export default {
mode: 'spa',
server: {
port: process.env.WEBSITE_PORT
},
env: {
development: process.env.NODE_ENV !== 'production',
version: process.env.npm_package_version,
URL: process.env.DOMAIN,
baseURL: `${process.env.DOMAIN}${process.env.ROUTE_PREFIX}`,
serviceName: process.env.SERVICE_NAME,
maxFileSize: process.env.MAX_SIZE,
chunkSize: process.env.CHUNK_SIZE,
maxLinksPerAlbum: process.env.MAX_LINKS_PER_ALBUM,
publicMode: process.env.PUBLIC_MODE,
userAccounts: process.env.USER_ACCOUNTS
},
srcDir: 'src/site/',
head: {
title: process.env.SERVICE_NAME,
@ -61,10 +62,8 @@ export default {
'~/plugins/vue-isyourpasswordsafe',
'~/plugins/vue-timeago',
'~/plugins/flexsearch',
'~/plugins/vuebar'
],
serverMiddleware: [
{ path: '/', handler: serveStatic(path.join(__dirname, 'uploads')) }
'~/plugins/vuebar',
'~/plugins/nuxt-client-init'
],
css: [],
modules: [
@ -80,6 +79,12 @@ export default {
preset: {
autoprefixer
}
},
extend(config, { isClient }) {
// Extend only webpack config for client-bundle
if (isClient) {
jetpack.write('dist/config.json', clientConfig);
}
}
}
};

View File

@ -10,13 +10,13 @@
},
"main": "src/_scripts/start.js",
"scripts": {
"setup": "yarn build && node src/setup.js",
"dev": "nuxt",
"setup": "node src/setup.js && yarn build && yarn migrate && yarn seed",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node src/api/structures/Server",
"dev": "nuxt",
"migrate": "yarn knex migrate:latest",
"seed": "yarn knex seed:run",
"api": "node src/api/structures/Server",
"site": "cross-env NODE_ENV=production nuxt start",
"update": "git pull && yarn install && yarn migrate && yarn build && yarn restart",
"restart": "pm2 restart lolisafe-api && pm2 restart lolisafe-website"
},

View File

@ -1,20 +1,9 @@
{
"apps" : [
{
"name": "lolisafe-api",
"name": "lolisafe",
"script": "npm",
"args": "run api",
"env": {
"NODE_ENV": "production"
},
"env_production" : {
"NODE_ENV": "production"
}
},
{
"name": "lolisafe-website",
"script": "npm",
"args": "run site",
"args": "run start",
"env": {
"NODE_ENV": "production"
},

View File

@ -23,16 +23,23 @@ class Server {
this.server.use(helmet());
this.server.use(cors({ allowedHeaders: ['Accept', 'Authorization', 'Cache-Control', 'X-Requested-With', 'Content-Type', 'albumId'] }));
this.server.use((req, res, next) => {
/*
This bypasses the headers.accept for album download, since it's accesed directly through the browser.
*/
// This bypasses the headers.accept for album download, since it's accesed directly through the browser.
if ((req.url.includes('/api/album/') || req.url.includes('/zip')) && req.method === 'GET') return next();
// This bypasses the headers.accept if we are accessing the frontend
if (!req.url.includes('/api/') && req.method === 'GET') return next();
if (req.headers.accept && req.headers.accept.includes('application/vnd.lolisafe.json')) return next();
return res.status(405).json({ message: 'Incorrect `Accept` header provided' });
});
this.server.use(bodyParser.urlencoded({ extended: true }));
this.server.use(bodyParser.json());
// this.server.use(rateLimiter);
// Serve the frontend if we are in production mode
if (process.env.NODE_ENV === 'production') {
this.server.use(express.static(path.join(__dirname, '..', '..', '..', 'dist')));
this.server.use(express.static(path.join(__dirname, '..', '..', '..', 'uploads')));
}
this.routesFolder = path.join(__dirname, '..', 'routes');
}

View File

@ -19,7 +19,7 @@ async function start() {
},
{
type: 'input',
query: 'Port to run the Website in:',
query: 'Port to run the Website in when in dev mode:',
handle: 'WEBSITE_PORT'
},
{

View File

@ -0,0 +1,3 @@
export default async ctx => {
await ctx.store.dispatch('nuxtClientInit', ctx);
};

View File

@ -1,3 +1,4 @@
import config from '../../../dist/config.json';
export const state = () => ({
loggedIn: false,
user: null,
@ -26,18 +27,8 @@ export const mutations = {
};
export const actions = {
async nuxtServerInit({ commit, dispatch }, { app, req }) {
commit('config', {
version: process.env.npm_package_version,
URL: process.env.DOMAIN,
baseURL: `${process.env.DOMAIN}${process.env.ROUTE_PREFIX}`,
serviceName: process.env.SERVICE_NAME,
maxFileSize: parseInt(process.env.MAX_SIZE, 10),
chunkSize: parseInt(process.env.CHUNK_SIZE, 10),
maxLinksPerAlbum: parseInt(process.env.MAX_LINKS_PER_ALBUM, 10),
publicMode: process.env.PUBLIC_MODE == 'true' ? true : false,
enableAccounts: process.env.USER_ACCOUNTS == 'true' ? true : false
});
async nuxtClientInit({ commit, dispatch }, { app, req }) {
commit('config', config);
const cookies = this.$cookies.getAll();
if (!cookies.token) return dispatch('logout');