diff --git a/config/defaults/development.json b/config/defaults/development.json new file mode 100644 index 0000000..ef38936 --- /dev/null +++ b/config/defaults/development.json @@ -0,0 +1,8 @@ +{ + "database": { + "user": "blog", + "password": null, + "host": "localhost", + "database": "blog" + } +} diff --git a/config/defaults/production.json b/config/defaults/production.json new file mode 100644 index 0000000..ef38936 --- /dev/null +++ b/config/defaults/production.json @@ -0,0 +1,8 @@ +{ + "database": { + "user": "blog", + "password": null, + "host": "localhost", + "database": "blog" + } +} diff --git a/config/helpers.js b/config/helpers.js new file mode 100644 index 0000000..5f56b9f --- /dev/null +++ b/config/helpers.js @@ -0,0 +1,18 @@ +const path = require('path'); + +const _root = path.resolve(__dirname, '..'); + +class Helpers { +}; + +Helpers.root = function(args) { + args = Array.prototype.slice.call(arguments, 0); + + return path.join.apply(path, [_root].concat(args)); +}; + +Helpers.assetsPath = function(_path) { + return path.posix.join('public/assets', _path); +}; + +module.exports = Helpers; \ No newline at end of file diff --git a/config/webpack.config.common.js b/config/webpack.config.common.js new file mode 100644 index 0000000..565f94a --- /dev/null +++ b/config/webpack.config.common.js @@ -0,0 +1,74 @@ +const webpack = require("webpack"); +const VueLoaderPlugin = require("vue-loader/lib/plugin"); +const MiniCSSExtractPlugin = require("mini-css-extract-plugin"); +const helpers = require("./helpers"); + +const isProd = process.env.NODE_ENV === 'production'; + +const webpackConfig = { + resolve: { + extensions: [".js", ".vue"], + alias: { + vue$: "vue/dist/vue.min.js", + "@": helpers.root("frontend") + } + }, + entry: { + blog: helpers.root("frontend", "blog-init") + }, + module: { + rules: [ + { + test: /\.vue$/, + use: [ + { + loader: "vue-loader", + options: { + loaders: { + scss: "vue-style-loader!css-loader!sass-loader", + sass: "vue-style-loader!css-loader!sass-loader?indentedSyntax" + } + } + } + ] + }, + { + test: /\.js$/, + use: [ "babel-loader" ], + include: [helpers.root("frontend")] + }, + { + test: /\.css$/, + use: [ + MiniCSSExtractPlugin.loader, + { loader: "css-loader", options: { sourceMap: !isProd } } + ] + }, + { + test: /\.scss$/, + use: [ + MiniCSSExtractPlugin.loader, + { loader: "css-loader", options: { sourceMap: !isProd } }, + { loader: "sass-loader", options: { sourceMap: !isProd } } + ] + }, + { + test: /\.woff(2)?(\?[a-z0-9]+)?$/, + loader: "url-loader", + options: { + limit: 10000, + mimetype: "application/font-woff" + } + }, + { + test: /\.(ttf|eot|svg)(\?[a-z0-9]+)?$/, + loader: "file-loader" + } + ] + }, + plugins: [ + new VueLoaderPlugin() + ] +}; + +module.exports = webpackConfig; diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js new file mode 100644 index 0000000..0f743fa --- /dev/null +++ b/config/webpack.config.dev.js @@ -0,0 +1,49 @@ +const webpack = require("webpack"); +const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const helpers = require("./helpers"); +// const environment = require("./env/dev.env"); +const MiniCSSExtractPlugin = require("mini-css-extract-plugin"); + +let webpackConfig = { + mode: "development", + devtool: "eval-cheap-module-source-map", + output: { + publicPath: "/", + filename: "js/[name].bundle.js" + }, + optimization: { + concatenateModules: true, + splitChunks: { + chunks: "initial" + } + }, + plugins: [ + new FriendlyErrorsPlugin(), + new MiniCSSExtractPlugin({ + filename: "css/[name].css" + }), + new HtmlWebpackPlugin({ + template: "frontend/templates/Index.html" + }) + ], + devServer: { + compress: true, + historyApiFallback: true, + host: "0.0.0.0", + hot: true, + overlay: true, + stats: { + normal: true + }, + proxy: { + "/api": { + target: "http://localhost:30010", + changeOrigin: false + } + }, + writeToDisk: false + } +}; + +module.exports = webpackConfig; diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js new file mode 100644 index 0000000..980220c --- /dev/null +++ b/config/webpack.config.prod.js @@ -0,0 +1,74 @@ +const { CleanWebpackPlugin } = require("clean-webpack-plugin"); +const path = require("path"); +const webpack = require("webpack"); +const HtmlWebpackPlugin = require("html-webpack-plugin"); +const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin"); +const MiniCSSExtractPlugin = require("mini-css-extract-plugin"); +const TerserPlugin = require("terser-webpack-plugin"); + +const helpers = require("./helpers"); + +const isProd = process.env.NODE_ENV === 'production'; + +const webpackConfig = { + mode: "production", + stats: { children: false }, + output: { + path: helpers.root("public/dist"), + publicPath: "/public/dist/", + filename: "js/[name].bundle.[fullhash:7].js" + }, + optimization: { + splitChunks: { + cacheGroups: { + styles: { + name: "styles", + test: /\.css$/, + chunks: "all", + enforce: true + } + } + }, + minimize: true, + minimizer: [ + new HtmlWebpackPlugin({ + chunks: ["blog"], + filename: helpers.root("public/index.html"), + template: "./frontend/templates/Index.html", + inject: true, + minify: { + removeComments: true, + collapseWhitespace: false, + preserveLineBreaks: true, + removeAttributeQuotes: true + } + }), + new OptimizeCSSAssetsPlugin({ + cssProcessorPluginOptions: { + preset: ["default", { discardComments: { removeAll: true } }] + } + }), + new TerserPlugin({ + test: /\.js(\?.*)?$/i, + }) + ] + }, + plugins: [ + new CleanWebpackPlugin(), // clean output folder + new MiniCSSExtractPlugin({ + filename: "css/[name].[fullhash:7].css" + }) + ] +}; + +if (!isProd) { + webpackConfig.devtool = "source-map"; +} + +// if (process.env.BUILD_REPORT) { +// const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") +// .BundleAnalyzerPlugin; +// webpackConfig.plugins.push(new BundleAnalyzerPlugin()); +// } + +module.exports = webpackConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..831ae1a --- /dev/null +++ b/package.json @@ -0,0 +1,47 @@ +{ + "scripts": { + "start": "cross-env NODE_ENV=production node api/webserver/server.js", + "dev": "cross-env NODE_ENV=development node api/webserver/server.js", + "db:setup": "node api/database/scripts/setupDatabase", + "db:seed": "node api/database/scripts/seedDatabase", + "db:teardown": "node api/database/scripts/teardownDatabase", + "build": "cross-env NODE_ENV=production webpack --progress", + "watch": "cross-env NODE_ENV=development webpack serve" + }, + "dependencies": { + "cross-env": "^7.0.3", + "express-http-context": "^1.2.4", + "jsqr": "^1.3.1", + "node-fetch": "^2.6.1", + "pg": "^8.5.1", + "qr-scanner": "^1.2.0", + "qrcode": "^1.4.4", + "vue": "^2.6.12", + "vue-router": "^3.4.9", + "vue-style-loader": "^4.1.2", + "winston": "^3.3.3" + }, + "devDependencies": { + "@babel/core": "^7.12.10", + "@babel/preset-env": "^7.12.10", + "babel-loader": "^8.2.2", + "clean-webpack-plugin": "^3.0.0", + "core-js": "^3.8.1", + "css-loader": "^5.0.1", + "file-loader": "^6.2.0", + "friendly-errors-webpack-plugin": "^1.7.0", + "html-webpack-plugin": "^4.5.0", + "mini-css-extract-plugin": "^1.3.3", + "optimize-css-assets-webpack-plugin": "^5.0.4", + "sass": "^1.30.0", + "sass-loader": "^10.1.0", + "terser-webpack-plugin": "^5.0.3", + "url-loader": "^4.1.1", + "vue-loader": "^15.9.5", + "vue-template-compiler": "^2.6.12", + "webpack": "^5.10.0", + "webpack-cli": "^4.2.0", + "webpack-dev-server": "^3.11.0", + "webpack-merge": "^5.5.0" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..5553e5e --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,13 @@ +const environment = (process.env.NODE_ENV || "development").trim(); +const { merge } = require("webpack-merge"); + +const commonConfig = require('./config/webpack.config.common'); +const devConfig = require("./config/webpack.config.dev"); +const prodConfig = require("./config/webpack.config.prod"); + +console.log('environment', process.env.NODE_ENV) +if (environment === "development") { + module.exports = merge(commonConfig, devConfig); +} else { + module.exports = merge(commonConfig, prodConfig); +}