├── .eslintignore
├── server
├── routes
│ ├── hello.js
│ └── index.js
├── core
│ ├── logger.js
│ ├── sequelize.js
│ └── express.js
├── config
│ ├── config.json
│ └── index.js
├── models
│ └── index.js
└── index.js
├── client
├── App.vue
├── index.js
├── routes.js
├── index.html
└── views
│ └── HelloWorld.vue
├── .eslintrc.js
├── .babelrc
├── config
├── prod.json
└── staging.json
├── utils
└── clean.js
├── webpack.config.dev.js
├── .gitignore
├── webpack.config.prod.js
├── README.md
├── webpack.config.js
└── package.json
/.eslintignore:
--------------------------------------------------------------------------------
1 | dist/*.js
2 | dist/**/*.js
--------------------------------------------------------------------------------
/server/routes/hello.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function (router) {
3 | router.route('/hello')
4 | .get((req, res) => {
5 | res.json('Hello World!')
6 | })
7 | }
8 |
--------------------------------------------------------------------------------
/client/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
12 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parserOptions: {
3 | parser: 'babel-eslint'
4 | },
5 | extends: [
6 | 'plugin:vue/recommended',
7 | 'standard'
8 | ],
9 | plugins: [
10 | 'vue'
11 | ]
12 | }
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "env",
5 | {
6 | "targets": {
7 | "browsers": [
8 | "last 2 Chrome versions", "IE 11"
9 | ]
10 | }
11 | }
12 | ]
13 | ]
14 | }
--------------------------------------------------------------------------------
/config/prod.json:
--------------------------------------------------------------------------------
1 | {
2 | "apps": [
3 | {
4 | "name": "hello-world-prod",
5 | "script": "server/index.js",
6 | "env": {
7 | "NODE_ENV": "production",
8 | "PORT": "8080"
9 | }
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/config/staging.json:
--------------------------------------------------------------------------------
1 | {
2 | "apps": [
3 | {
4 | "name": "hello-world-staging",
5 | "script": "server/index.js",
6 | "env": {
7 | "NODE_ENV": "staging",
8 | "PORT": "8080"
9 | }
10 | }
11 | ]
12 | }
--------------------------------------------------------------------------------
/client/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | import router from './routes'
4 |
5 | import App from './App.vue'
6 |
7 | import 'isomorphic-fetch'
8 |
9 | new Vue({
10 | router,
11 | render: createEle => createEle(App)
12 | }).$mount('#app')
13 |
--------------------------------------------------------------------------------
/server/core/logger.js:
--------------------------------------------------------------------------------
1 | const winston = require('winston')
2 |
3 | winston.level = 'debug'
4 | const logger = new (winston.Logger)({
5 | transports: [
6 | // colorize the output to the console
7 | new (winston.transports.Console)({
8 | colorize: true,
9 | prettyPrint: true
10 | })
11 | ]
12 | })
13 |
14 | module.exports = logger
15 |
--------------------------------------------------------------------------------
/client/routes.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | import HelloWorld from './views/HelloWorld.vue'
5 |
6 | Vue.use(VueRouter)
7 |
8 | const siteRoutes = [{
9 | path: '/',
10 | component: HelloWorld
11 | }]
12 |
13 | const vueRouter = new VueRouter({
14 | mode: 'history',
15 | routes: siteRoutes
16 | })
17 |
18 | export default vueRouter
19 |
--------------------------------------------------------------------------------
/client/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Hello World
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/server/config/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "test": {
3 | "PORT": 3000,
4 | "DATABASE_URI": "postgres://user:password@localhost:5432/testing"
5 | },
6 | "development": {
7 | "PORT": 3000,
8 | "DATABASE_URI": "postgres://user:password@localhost:5432/development"
9 | },
10 | "production": {
11 | "PORT": 8080,
12 | "DATABASE_URI": "postgres://user:password@localhost:5432/portfolio"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/server/routes/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const path = require('path')
3 | const fs = require('fs')
4 |
5 | const basename = path.basename(module.filename)
6 | const router = express.Router()
7 |
8 | fs.readdirSync(__dirname)
9 | .filter(file => (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'))
10 | .forEach((file) => {
11 | require(`./${file}`)(router)
12 | })
13 |
14 | module.exports = router
15 |
--------------------------------------------------------------------------------
/server/core/sequelize.js:
--------------------------------------------------------------------------------
1 | const logger = require('./logger')
2 |
3 | const config = require('../config')
4 |
5 | const Sequelize = require('sequelize')
6 |
7 | const sequelize = new Sequelize(config.DATABASE_URI)
8 |
9 | sequelize
10 | .authenticate()
11 | .then(() => {
12 | logger.info('Successfully established connection to database')
13 | })
14 | .catch((err) => {
15 | logger.error('Unable to connect to database', err)
16 | })
17 |
18 | module.exports = sequelize
19 |
--------------------------------------------------------------------------------
/client/views/HelloWorld.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Hello World Title
4 | {{ text }}
5 |
6 |
7 |
8 |
21 |
22 |
28 |
--------------------------------------------------------------------------------
/utils/clean.js:
--------------------------------------------------------------------------------
1 | const logger = require('../server/core/logger')
2 | const dayjs = require('dayjs')
3 | const chalk = require('chalk')
4 |
5 | logger.info()
6 | logger.info(chalk.bold('---------------------[ Cleaning DB at %s ]---------------------------'), dayjs()
7 | .format('YYYY-MM-DD HH:mm:ss.SSS'))
8 |
9 | const models = require('../server/models')
10 |
11 | // sync models
12 | models.sequelize.sync({ force: false })
13 | .then(() => {
14 | logger.info(chalk.bold('---------------------[ Cleaned DB at %s ]---------------------------'), dayjs()
15 | .format('YYYY-MM-DD HH:mm:ss.SSS'))
16 | process.exit()
17 | })
18 |
--------------------------------------------------------------------------------
/server/models/index.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const sequelize = require('../core/sequelize')
4 |
5 | const db = {}
6 |
7 | const basename = path.basename(module.filename)
8 |
9 | // Filter non "." starting files and index.js locally
10 | fs.readdirSync(__dirname)
11 | .filter(file => (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'))
12 | .forEach((file) => {
13 | const model = sequelize.import(path.join(__dirname, file))
14 | db[model.name] = model
15 | })
16 |
17 | Object.keys(db)
18 | .forEach((modelName) => {
19 | if ('associate' in db[modelName]) {
20 | db[modelName].associate(db)
21 | }
22 | })
23 |
24 | db.sequelize = sequelize
25 |
26 | module.exports = db
27 |
--------------------------------------------------------------------------------
/webpack.config.dev.js:
--------------------------------------------------------------------------------
1 | const config = {}
2 |
3 | const webpack = require('webpack')
4 |
5 | config.mode = "development"
6 |
7 | config.devServer = {
8 | hot: true
9 | }
10 |
11 | config.entry = ['eventsource-polyfill', 'babel-polyfill', 'webpack-hot-middleware/client?name=frontPage', './client/index.js']
12 |
13 | config.plugins = [
14 | new webpack.HotModuleReplacementPlugin()
15 | ]
16 |
17 | config.module = {
18 | rules: [
19 | {
20 | test: /\.css$/,
21 | use: [
22 | 'vue-style-loader',
23 | 'css-loader'
24 | ]
25 | },
26 | {
27 | test: /\.scss$/,
28 | use: [{
29 | loader: "style-loader"
30 | }, {
31 | loader: "css-loader"
32 | }, {
33 | loader: "sass-loader"
34 | }]
35 | }
36 | ]
37 | }
38 |
39 | module.exports = config
40 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | const config = require('./config')
2 | const logger = require('./core/logger')
3 | const dayjs = require('dayjs')
4 | const chalk = require('chalk')
5 |
6 | logger.info()
7 | logger.info(chalk.bold('---------------------[ Server starting at %s ]---------------------------'), dayjs()
8 | .format('YYYY-MM-DD HH:mm:ss.SSS'))
9 |
10 | const models = require('./models')
11 | const app = require('./core/express')
12 |
13 | const startServer = () => {
14 | // Start init
15 | app.listen(config.PORT, () => {
16 | logger.info(`Server running at port: ${chalk.green(config.PORT)}`)
17 | })
18 | }
19 |
20 | // sync models
21 | if (!config.isTestMode() && config.resyncEnabled() === true) {
22 | models.sequelize.sync({ force: true })
23 | .then(startServer)
24 | } else {
25 | startServer()
26 | }
27 |
28 | module.exports = app
29 |
--------------------------------------------------------------------------------
/server/config/index.js:
--------------------------------------------------------------------------------
1 | const _ = require('lodash')
2 |
3 | const config = require('./config.json')
4 |
5 | const webpackConfig = require('../../webpack.config')
6 |
7 | const curConfig = {
8 | isDevMode () {
9 | return !process.env.NODE_ENV || process.env.NODE_ENV === 'development'
10 | },
11 | isStagingMode () {
12 | return process.env.NODE_ENV === 'staging'
13 | },
14 | isProdMode () {
15 | return process.env.NODE_ENV === 'production'
16 | },
17 | isTestMode () {
18 | return process.env.NODE_ENV === 'test'
19 | },
20 | resyncEnabled () {
21 | return false
22 | },
23 | webpackConfig
24 | }
25 |
26 | let resConfig = {}
27 |
28 | if (process.env.NODE_ENV) {
29 | resConfig = config[process.env.NODE_ENV]
30 | } else {
31 | resConfig = config.development
32 | }
33 |
34 | const configs = _.merge(resConfig, curConfig)
35 |
36 | // Additional Configs
37 | configs.imageDir = `${configs.PUBLIC_DIR}/images`
38 |
39 | module.exports = configs
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### NodeJS Gitignore
2 |
3 | # Logs
4 | logs
5 | *.log
6 | npm-debug.log*
7 | yarn-debug.log*
8 | yarn-error.log*
9 |
10 | # Runtime data
11 | pids
12 | *.pid
13 | *.seed
14 | *.pid.lock
15 |
16 | # Directory for instrumented libs generated by jscoverage/JSCover
17 | lib-cov
18 |
19 | # Coverage directory used by tools like istanbul
20 | coverage
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26 | .grunt
27 |
28 | # Bower dependency directory (https://bower.io/)
29 | bower_components
30 |
31 | # node-waf configuration
32 | .lock-wscript
33 |
34 | # Compiled binary addons (http://nodejs.org/api/addons.html)
35 | build/Release
36 |
37 | # Dependency directories
38 | node_modules/
39 | jspm_packages/
40 |
41 | # Typescript v1 declaration files
42 | typings/
43 |
44 | # Optional npm cache directory
45 | .npm
46 |
47 | # Optional eslint cache
48 | .eslintcache
49 |
50 | # Optional REPL history
51 | .node_repl_history
52 |
53 | # Output of 'npm pack'
54 | *.tgz
55 |
56 | # Yarn Integrity file
57 | .yarn-integrity
58 |
59 | # dotenv environment variables file
60 | .env
61 |
62 | # output of builds
63 | /dist
64 |
--------------------------------------------------------------------------------
/server/core/express.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const helmet = require('helmet')
3 | const helmetCsp = require('helmet-csp')
4 | const webpack = require('webpack')
5 | const bodyParser = require('body-parser')
6 |
7 | const config = require('../config')
8 |
9 | const app = express()
10 |
11 | // Projection
12 | app.use(helmet.xssFilter())
13 | app.use(helmet.frameguard())
14 | app.use(helmet.hidePoweredBy())
15 |
16 | // Defaults
17 | app.use(bodyParser.urlencoded({
18 | extended: false
19 | }))
20 | app.use(bodyParser.json())
21 |
22 | // public folder
23 | app.use('/public', express.static('static'))
24 |
25 | // API
26 | const router = require('../routes')
27 |
28 | app.use('/api', router)
29 |
30 | app.use(require('connect-history-api-fallback')({
31 | index: '/index.html',
32 | rewrites: [
33 | ],
34 | verbose: false
35 | }))
36 |
37 | // Hot middleware
38 | if (config.isDevMode()) {
39 | const compiler = webpack(config.webpackConfig)
40 |
41 | app.use(require('webpack-dev-middleware')(compiler, {
42 | stats: {
43 | colors: true
44 | }
45 | }))
46 | app.use(require('webpack-hot-middleware')(compiler))
47 | } else {
48 | app.use(helmetCsp({
49 | directives: {
50 | defaultSrc: ["'self'"],
51 | scriptSrc: ["'self'"],
52 | styleSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'"]
53 | }
54 | }))
55 | app.use(express.static('dist'))
56 | }
57 |
58 | module.exports = app
59 |
--------------------------------------------------------------------------------
/webpack.config.prod.js:
--------------------------------------------------------------------------------
1 | const config = {}
2 |
3 | const CssNano = require('cssnano')
4 | const webpack = require('webpack')
5 | const MiniCssExtractPlugin = require('mini-css-extract-plugin')
6 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
7 |
8 | config.mode = "production"
9 |
10 | config.entry = ['babel-polyfill', './client/index.js']
11 |
12 | config.optimization = {
13 | minimizer: [
14 | new UglifyJsPlugin({
15 | cache: true,
16 | parallel: true,
17 | uglifyOptions: {
18 | compress: false,
19 | ecma: 6,
20 | mangle: true
21 | },
22 | sourceMap: false
23 | })
24 | ]
25 | }
26 | config.plugins = [
27 | new webpack.optimize.AggressiveMergingPlugin(),
28 | new webpack.optimize.OccurrenceOrderPlugin(),
29 | new webpack.optimize.ModuleConcatenationPlugin(),
30 | new webpack.DefinePlugin({
31 | 'process.env': {
32 | NODE_ENV: '"production"'
33 | }
34 | }),
35 | new MiniCssExtractPlugin({
36 | filename: 'main.css'
37 | })
38 | ]
39 |
40 | config.module = {
41 | rules: [
42 | {
43 | test: /\.(css|sass|scss)$/,
44 | use: [
45 | MiniCssExtractPlugin.loader,
46 | {
47 | loader: 'css-loader',
48 | options: {
49 | importLoaders: 2,
50 | sourceMap: false
51 | }
52 | },
53 | {
54 | loader: 'postcss-loader',
55 | options: {
56 | plugins: () => [
57 | require('autoprefixer')
58 | ],
59 | sourceMap: false
60 | }
61 | },
62 | {
63 | loader: 'sass-loader',
64 | options: {
65 | sourceMap: false
66 | }
67 | }
68 | ]
69 | }
70 | ]
71 | }
72 |
73 |
74 | module.exports = config
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Nodejs - Vue - Postgresql Sample Project
2 | This is an example project featuring the use of nodejs, vuejs and postgresql in the same project
3 |
4 | ## Requirements
5 | 1. Nodejs/npm/pm2
6 | 2. Postgresql
7 |
8 | If you are running on any ubuntu variants, you can run this to get things started quickly
9 | ```bash
10 | echo "Installing Nodejs"
11 | sudo apt-get install nodejs -y
12 | sudo ln -s "$(which nodejs)" /usr/bin/node
13 | sudo apt-get install npm -y
14 |
15 | echo "Upgrade nodejs"
16 | sudo npm install n -g
17 | sudo n stable
18 |
19 | echo "Installing Postgres"
20 | sudo apt-get install postgresql postgresql-contrib
21 | ```
22 |
23 | For windows, install following executables
24 |
25 | [Installing nodejs on windows](blog.teamtreehouse.com/install-node-js-npm-windows)
26 |
27 | [Installing postgresql on windows](https://www.labkey.org/Documentation/wiki-page.view?name=installPostgreSQLWindows)
28 |
29 | For macos, get brew and execute following commands
30 | ```shell
31 | brew install node
32 | brew install postgresql
33 | ```
34 |
35 | Then upgrade nodejs and install the dependencies
36 | ```powershell
37 | npm install n -g
38 | n stable
39 | npm install -g pm2
40 | ```
41 |
42 | ## Setting up
43 | Before running the code, we need to setup postgresql and append the postgresql details in server/config/config.json
44 |
45 | Open up the psql console and run the following command
46 | ```psql
47 | CREATE USER user WITH PASSWORD 'secret';
48 | CREATE DATABASE development;
49 | GRANT ALL PRIVILEGES ON DATABASE development TO user;
50 | ```
51 |
52 | then modify the config.json DATABASE_URI params with the following (assuming using development environment)
53 | ```json
54 | "development": {
55 | "PORT": 3000,
56 | "DATABASE_URI": "postgres://user:secret@localhost:5432/development"
57 | },
58 | ```
59 |
60 | ## Usage
61 | Simply run following commands on the root folder to start
62 |
63 | ```bash
64 | npm install
65 | npm start
66 | ```
67 |
68 | # Changelog
69 |
70 | ## Breaking Change
71 | - Added support for Webpack4, ESLint and Babel 7
72 | - Cleaned code and structure
73 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const HtmlWebpackPlugin = require('html-webpack-plugin')
3 | const { VueLoaderPlugin } = require('vue-loader')
4 |
5 | const merge = require('webpack-merge')
6 |
7 | /**
8 | * Environment type
9 | */
10 | const DEV = process.env.NODE_ENV === 'development'
11 | const PROD = process.env.NODE_ENV === 'production'
12 | const STAGING = process.env.NODE_ENV === 'staging'
13 |
14 | let config = {
15 | name: 'frontPage'
16 | }
17 |
18 | config.output = {
19 | path: path.resolve(__dirname, './dist'),
20 | filename: 'build.js',
21 | publicPath: '/'
22 | }
23 |
24 | config.resolve = {
25 | alias: {
26 | vue: 'vue/dist/vue.common.js',
27 | styles: path.resolve(__dirname, './client/assets/stylesheet'),
28 | components: path.resolve(__dirname, './client/components')
29 | }
30 | }
31 |
32 | config.module = {
33 | rules: [
34 | /**
35 | * Linting
36 | */
37 | {
38 | test: /\.(js|vue)$/,
39 | use: 'eslint-loader',
40 | enforce: 'pre'
41 | },
42 | /**
43 | * Compile
44 | */
45 | {
46 | test: /\.js$/,
47 | exclude: /node_modules/,
48 | use: {
49 | loader: 'babel-loader',
50 | }
51 | },
52 | {
53 | test: /\.vue$/,
54 | use: 'vue-loader'
55 | },
56 | {
57 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
58 | use: [{
59 | loader: 'url-loader',
60 | options: {
61 | limit: 10000
62 | }
63 | }]
64 | },
65 | {
66 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
67 | use: [{
68 | loader: 'url-loader',
69 | options: {
70 | limit: 10000
71 | }
72 | }]
73 | }
74 | ]
75 | }
76 |
77 | config.plugins = [
78 | new HtmlWebpackPlugin({
79 | filename: path.join(__dirname, 'dist/index.html'),
80 | template: path.join(__dirname, 'client/index.html'),
81 | inject: true
82 | }),
83 | new VueLoaderPlugin()
84 | ]
85 |
86 | if (DEV) {
87 | config = merge(config, require('./webpack.config.dev.js'))
88 | } else if (PROD || STAGING) {
89 | config = merge(config, require('./webpack.config.prod.js'))
90 | }
91 | module.exports = [config]
92 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "helloworld",
3 | "description": "hello world page",
4 | "version": "0.1.0",
5 | "author": "helloworld@example.com",
6 | "scripts": {
7 | "test": "nyc mocha --timeout=3000",
8 | "lint": "eslint --ext .js,.vue . client/** server/**",
9 | "lint:fix": "eslint --ext .js,.vue --fix . client/** server/**",
10 | "start": "npm run start:dev",
11 | "start:dev": "cross-env NODE_ENV=development nodemon server/index.js --ignore client/ --ignore admin/",
12 | "start:staging": "npm run build:prod && npm run node:staging",
13 | "start:prod": "npm run build:prod && npm run node:prod",
14 | "clean:dev": "cross-env NODE_ENV=development node utils/clean.js",
15 | "clean:staging": "cross-env NODE_ENV=staging node utils/clean.js",
16 | "clean:prod": "cross-env NODE_ENV=production node utils/clean.js",
17 | "migrate:dev": "cd server && cross-env NODE_ENV=development ../node_modules/.bin/sequelize db:migrate",
18 | "migrate:staging": "cd server && cross-env NODE_ENV=staging ../node_modules/.bin/sequelize db:migrate",
19 | "migrate:prod": "cd server && cross-env NODE_ENV=production ../node_modules/.bin/sequelize db:migrate",
20 | "node:staging": "pm2 start config/staging.json",
21 | "node:prod": "pm2 start config/prod.json",
22 | "build:prod": "npm run webpack:prod",
23 | "webpack:prod": "cross-env NODE_ENV=production webpack --progress --hide-modules --mode production",
24 | "webpack:dev": "cross-env NODE_ENV=development webpack --progress --hide-modules --mode development"
25 | },
26 | "devDependencies": {
27 | "babel-core": "^6.26.3",
28 | "babel-eslint": "^8.2.6",
29 | "babel-loader": "^7.1.5",
30 | "babel-polyfill": "^6.26.0",
31 | "babel-preset-env": "^1.7.0",
32 | "cross-env": "^5.2.1",
33 | "css-loader": "^0.28.11",
34 | "eslint": "^4.19.1",
35 | "eslint-config-standard": "^12.0.0",
36 | "eslint-loader": "^2.2.1",
37 | "eslint-plugin-import": "^2.20.1",
38 | "eslint-plugin-node": "^6.0.1",
39 | "eslint-plugin-promise": "^3.8.0",
40 | "eslint-plugin-standard": "^3.1.0",
41 | "eslint-plugin-vue": "^4.7.1",
42 | "eventsource-polyfill": "^0.9.6",
43 | "extract-text-webpack-plugin": "^3.0.2",
44 | "hoek": "^5.0.4",
45 | "html-webpack-plugin": "^3.2.0",
46 | "isomorphic-fetch": "^2.2.1",
47 | "mini-css-extract-plugin": "^0.4.5",
48 | "nodemon": "^1.19.4",
49 | "path": "^0.12.7",
50 | "pm2": "^2.10.4",
51 | "postcss-loader": "^2.1.6",
52 | "sass-loader": "^7.3.1",
53 | "style-loader": "^0.21.0",
54 | "vue-loader": "^15.9.0",
55 | "vue-template-compiler": "^2.6.11",
56 | "webpack": "^4.42.0",
57 | "webpack-cli": "^2.1.5",
58 | "webpack-merge": "^4.2.2"
59 | },
60 | "dependencies": {
61 | "body-parser": "^1.19.0",
62 | "connect-history-api-fallback": "^1.6.0",
63 | "dayjs": "^1.8.22",
64 | "es6-promise": "^4.2.8",
65 | "express": "^4.17.1",
66 | "fs": "0.0.1-security",
67 | "helmet": "^3.21.3",
68 | "helmet-csp": "^2.9.5",
69 | "lodash": "^4.17.15",
70 | "node-sass": "^7.0.0",
71 | "pg": "^7.18.2",
72 | "sequelize": "^4.44.4",
73 | "vue": "^2.6.11",
74 | "vue-localstorage": "^0.6.2",
75 | "vue-router": "^3.1.6",
76 | "webpack-dev-middleware": "^3.7.2",
77 | "webpack-hot-middleware": "^2.25.0",
78 | "winston": "^2.4.4"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------