diff --git a/client/package.json b/client/package.json
index 4fdc8bb..fa470c3 100644
--- a/client/package.json
+++ b/client/package.json
@@ -3,44 +3,41 @@
"version": "0.0.1",
"description": "Template for creating a new project with a node (express) server and a react client",
"dependencies": {
- "babel-core": "6.25.0",
- "babel-loader": "7.1.1",
- "babel-plugin-syntax-dynamic-import": "6.18.0",
- "babel-plugin-transform-object-rest-spread": "6.23.0",
- "babel-preset-es2015": "6.24.0",
- "babel-preset-react": "6.23.0",
- "case-sensitive-paths-webpack-plugin": "2.1.1",
- "css-loader": "0.28.0",
- "es6-promise": "4.1.0",
- "extract-text-webpack-plugin": "2.1.2",
- "fast-sass-loader": "1.2.5",
- "node-sass": "4.5.2",
- "path": "0.12.7",
- "raw-loader": "0.5.1",
- "react-router-routing-helpers": "1.0.3",
- "simple-client-request": "1.0.8",
- "style-loader": "0.16.1",
- "uglifyjs-webpack-plugin": "1.0.1",
- "webpack": "3.5.3",
- "webpack-node-externals": "1.6.0"
+ "@babel/core": "^7.23.9",
+ "@babel/preset-env": "^7.23.9",
+ "@babel/preset-react": "^7.23.3",
+ "babel-loader": "^9.1.3",
+ "case-sensitive-paths-webpack-plugin": "^2.4.0",
+ "css-loader": "^6.10.0",
+ "mini-css-extract-plugin": "^2.8.1",
+ "node-sass": "^9.0.0",
+ "path": "^0.12.7",
+ "raw-loader": "^4.0.2",
+ "react-router-routing-helpers": "^1.0.3",
+ "simple-client-request": "^1.0.8",
+ "style-loader": "^3.3.4",
+ "terser-webpack-plugin": "^5.3.10",
+ "webpack": "^5.89.0",
+ "webpack-cli": "^5.1.4",
+ "webpack-node-externals": "^3.0.0"
},
"peerDependencies": {
- "jquery": "3.2.1",
- "prop-types": "15.6.1",
- "react": "16.3.2",
- "react-dom": "16.3.2",
- "react-router-dom": "4.2.2"
+ "jquery": "^3.7.1",
+ "prop-types": "^15.8.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.0"
},
"devDependencies": {
- "jquery": "3.2.1",
- "prop-types": "15.6.1",
- "react": "16.3.2",
- "react-dom": "16.3.2",
- "react-router-dom": "4.2.2",
- "webpack-dev-server": "2.7.1"
+ "jquery": "^3.7.1",
+ "prop-types": "^15.8.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.0",
+ "webpack-dev-server": "^4.15.1"
},
"scripts": {
- "start": "webpack-dev-server --config webpack.config.js --open --env=dev --hot",
+ "start": "webpack serve --config webpack.config.js --open --env=dev --hot",
"compile": "NODE_ENV=production webpack --env=prod --config webpack.config.js --display verbose --progress",
"compile-windows": "SET NODE_ENV=production & webpack --env=prod --config webpack.config.js --display verbose --progress",
"compile-dev": "webpack --env=dev --config webpack.config.js",
diff --git a/client/src/App.js b/client/src/App.js
index 33575f3..8af1302 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -1,33 +1,27 @@
'use strict';
import React from 'react';
-import {BrowserRouter, Route, Redirect, Switch} from 'react-router-dom';
+import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import layoutStyles from './styleMain/layout.sass';
-import {demoPages} from './routes';
-import {DemoModal} from './containers/modals';
+import { demoPages } from './routes';
+import { DemoModal } from './containers/modals';
+import { HomePage, DemoPage } from './containers/pages';
-import {HomePage, DemoPage} from './containers/pages';
-
-class App extends React.Component {
- //noinspection JSMethodCanBeStatic
- render () {
- return (
-
- );
- }
+function App() {
+ return (
+
+
+
+ } />
+ } />
+ } />
+
+
+
+
+ );
}
export default App;
\ No newline at end of file
diff --git a/client/src/index.js b/client/src/index.js
index 36a89dc..c1f4d95 100644
--- a/client/src/index.js
+++ b/client/src/index.js
@@ -1,17 +1,14 @@
'use strict';
import React from 'react';
-import ReactDOM from 'react-dom';
+import { createRoot } from 'react-dom/client';
import App from './App';
-function Main () {
- return (
-
- );
+function Main() {
+ return ;
}
-ReactDOM.render(
- ,
- document.getElementById('root')
-);
\ No newline at end of file
+const container = document.getElementById('root');
+const root = createRoot(container);
+root.render();
\ No newline at end of file
diff --git a/client/webpack.config.js b/client/webpack.config.js
index ff5370f..1a79324 100644
--- a/client/webpack.config.js
+++ b/client/webpack.config.js
@@ -7,21 +7,18 @@ module.exports = function(env) {
if (env === 'ssr') {
generalConfig = require('./webpack/ssrConfig').webpack;
- }
- else {
+ } else {
generalConfig = require('./webpack/clientConfig').webpack;
}
+ const envConfig = require(`./webpack/webpack.${env}.js`);
+ const execConfig = { ...generalConfig, ...envConfig };
- const envConfig = require('./webpack/webpack.' + env + '.js');
- const execConfig = Object.assign({}, generalConfig, envConfig);
- console.log(JSON.stringify(execConfig));
-
- console.log('*******************');
- console.log('webpack ' + env + ' setup\n' +
- 'Compiling entry point is ' + JSON.stringify(execConfig.entry) + '\n' +
- 'Compiling files to ' + execConfig.output.path + ' folder.......');
- console.log('*******************');
+ console.log('\n*******************');
+ console.log(`Webpack ${env} Configuration:`);
+ console.log(`Entry point: ${JSON.stringify(execConfig.entry)}`);
+ console.log(`Output path: ${execConfig.output.path}`);
+ console.log('*******************\n');
return execConfig;
};
\ No newline at end of file
diff --git a/client/webpack/clientConfig.js b/client/webpack/clientConfig.js
index b9f2334..c7f41a7 100644
--- a/client/webpack/clientConfig.js
+++ b/client/webpack/clientConfig.js
@@ -15,21 +15,39 @@ const configPaths = {
module.exports.configPaths = configPaths;
module.exports.webpack = {
- entry: configPaths.appDir + '/index.js',
+ entry: {
+ main: path.join(configPaths.appDir, 'index.js')
+ },
output: {
- path: configPaths.basePublicPath + configPaths.buildDir,
- filename: '[name].bundle.js',
- chunkFilename: '[name].bundle.js',
- publicPath: configPaths.buildDir + '/'
+ path: path.join(configPaths.basePublicPath, configPaths.buildDir),
+ filename: '[name].[contenthash].bundle.js',
+ chunkFilename: '[name].[contenthash].bundle.js',
+ publicPath: configPaths.buildDir + '/',
+ clean: true
+ },
+ resolve: {
+ extensions: ['.js', '.jsx', '.json'],
+ modules: ['node_modules', APP_DIR]
},
externals: {
- 'jquery': 'var jQuery',
-
- 'react': 'var React',
- 'react-dom': 'var ReactDOM',
- 'prop-types': 'var PropTypes',
-
- 'react-router': 'var ReactRouterDOM',
- 'react-router-dom': 'var ReactRouterDOM',
+ jquery: 'jQuery',
+ react: 'React',
+ 'react-dom': 'ReactDOM',
+ 'prop-types': 'PropTypes',
+ 'react-router-dom': 'ReactRouterDOM'
},
+ optimization: {
+ moduleIds: 'deterministic',
+ runtimeChunk: 'single',
+ splitChunks: {
+ chunks: 'all',
+ cacheGroups: {
+ vendor: {
+ test: /[\\/]node_modules[\\/]/,
+ name: 'vendors',
+ chunks: 'all'
+ }
+ }
+ }
+ }
};
\ No newline at end of file
diff --git a/client/webpack/webpack.dev.js b/client/webpack/webpack.dev.js
index b3285cd..3474607 100644
--- a/client/webpack/webpack.dev.js
+++ b/client/webpack/webpack.dev.js
@@ -1,65 +1,97 @@
const webpack = require('webpack');
-//noinspection JSUnresolvedVariable
-const DefinePlugin = webpack.DefinePlugin; // Replace code with specific values
-const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); // Force case sensitive on client paths upon require/import
+const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {appDir, basePublicPath, buildDir} = require('./clientConfig').configPaths;
module.exports = {
+ mode: 'development',
module: {
rules: [
{
- test: /\.js$/,
+ test: /\.(js|jsx)$/,
include: appDir,
use: {
loader: 'babel-loader',
options: {
- presets: [['es2015', {modules: false}]],
- plugins: ['syntax-dynamic-import']
+ presets: [
+ ['@babel/preset-env', { modules: false }],
+ '@babel/preset-react'
+ ],
+ plugins: ['@babel/plugin-syntax-dynamic-import']
}
}
},
{
- test: /\.jsx$/,
- include: appDir,
- use: {
- loader: 'babel-loader'
- }
- },
- {
- test: /\.global\.sass$/, // only files with .global will go through this loader. e.g. app.global.sass
- loaders: [
+ test: /\.global\.sass$/,
+ use: [
'style-loader',
- 'css-loader?importLoaders=1',
- 'fast-sass-loader'
+ {
+ loader: 'css-loader',
+ options: {
+ importLoaders: 1,
+ sourceMap: true
+ }
+ },
+ {
+ loader: 'sass-loader',
+ options: {
+ sourceMap: true
+ }
+ }
]
},
{
- test: /^((?!\.global).)*\.sass$/, // anything with .global will not go through css modules loader
+ test: /^((?!\.global).)*\.sass$/,
include: appDir,
use: [
'style-loader',
- 'css-loader?importLoaders=1&modules&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
- 'fast-sass-loader'
+ {
+ loader: 'css-loader',
+ options: {
+ importLoaders: 1,
+ modules: {
+ localIdentName: '[path]___[name]__[local]___[hash:base64:5]'
+ },
+ sourceMap: true
+ }
+ },
+ {
+ loader: 'sass-loader',
+ options: {
+ sourceMap: true
+ }
+ }
]
}
]
},
devServer: {
- contentBase: basePublicPath,
+ static: {
+ directory: basePublicPath
+ },
port: 3000,
proxy: {
'/': process.env.API_HOST || 'http://localhost:4300'
},
- publicPath: buildDir + '/'
+ hot: true,
+ historyApiFallback: true,
+ client: {
+ overlay: {
+ errors: true,
+ warnings: false
+ }
+ }
},
- devtool: 'source-map',
+ devtool: 'eval-source-map',
plugins: [
- new DefinePlugin({
- 'process.env': {
- 'NODE_ENV': JSON.stringify('dev')
- }
+ new webpack.DefinePlugin({
+ 'process.env.NODE_ENV': JSON.stringify('development')
}),
new CaseSensitivePathsPlugin(),
+ new MiniCssExtractPlugin({
+ filename: '[name].css',
+ chunkFilename: '[id].css'
+ })
]
};
diff --git a/client/webpack/webpack.prod.js b/client/webpack/webpack.prod.js
index 8e08ddd..99a0b0f 100644
--- a/client/webpack/webpack.prod.js
+++ b/client/webpack/webpack.prod.js
@@ -1,84 +1,98 @@
'use strict';
const webpack = require('webpack');
-//noinspection JSUnresolvedVariable
-const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); // Uglify code
-//noinspection JSUnresolvedVariable
-const DefinePlugin = webpack.DefinePlugin; // Replace code with specific values
-
-const ExtractTextPlugin = require("extract-text-webpack-plugin");
-
-const extractSass = new ExtractTextPlugin({
- filename: "bundle.css?[hash]-[chunkhash]-[contenthash]-[name]",
- allChunks: true,
- disable: process.env.NODE_ENV !== "production"
-});
+const TerserPlugin = require('terser-webpack-plugin');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const {appDir} = require('./clientConfig').configPaths;
module.exports = {
+ mode: 'production',
module: {
rules: [
{
- test: /\.js$/,
+ test: /\.(js|jsx)$/,
include: appDir,
use: {
loader: 'babel-loader',
options: {
- presets: [['es2015', {modules: false}]],
- plugins: ['syntax-dynamic-import']
+ presets: [
+ ['@babel/preset-env', { modules: false }],
+ '@babel/preset-react'
+ ],
+ plugins: ['@babel/plugin-syntax-dynamic-import']
}
}
},
{
- test: /\.jsx$/,
- include: appDir,
- use: {
- loader: 'babel-loader'
- }
- },
- {
- test: /\.global\.sass$/, // only files with .global will go through this loader. e.g. app.global.sass
- use: ExtractTextPlugin.extract({
- use: [{
- loader: "css-loader?importLoaders=1",
+ test: /\.global\.sass$/,
+ use: [
+ MiniCssExtractPlugin.loader,
+ {
+ loader: 'css-loader',
+ options: {
+ importLoaders: 1,
+ sourceMap: false
+ }
+ },
+ {
+ loader: 'sass-loader',
options: {
sourceMap: false
}
- }, {
- loader: "fast-sass-loader"
- }],
- // use style-loader in development
- fallback: "style-loader"
- }),
+ }
+ ]
},
{
- test: /^((?!\.global).)*\.sass$/, // anything with .global will not go through css modules loader
+ test: /^((?!\.global).)*\.sass$/,
include: appDir,
- use: ExtractTextPlugin.extract({
- use: [{
- loader: "css-loader?importLoaders=1&modules&localIdentName=[path]___[name]__[local]",
+ use: [
+ MiniCssExtractPlugin.loader,
+ {
+ loader: 'css-loader',
options: {
- modules: true,
- sourceMap: false,
- minimize: true
+ importLoaders: 1,
+ modules: {
+ localIdentName: '[hash:base64:5]'
+ },
+ sourceMap: false
+ }
+ },
+ {
+ loader: 'sass-loader',
+ options: {
+ sourceMap: false
}
- }, {
- loader: "fast-sass-loader"
- }],
- // use style-loader in development
- fallback: "style-loader"
- }),
+ }
+ ]
}
]
},
+ optimization: {
+ minimize: true,
+ minimizer: [
+ new TerserPlugin({
+ terserOptions: {
+ compress: {
+ drop_console: true
+ },
+ format: {
+ comments: false
+ }
+ },
+ extractComments: false
+ }),
+ new CssMinimizerPlugin()
+ ]
+ },
plugins: [
- extractSass,
- new DefinePlugin({
- 'process.env': {
- 'NODE_ENV': JSON.stringify('production')
- }
+ new webpack.DefinePlugin({
+ 'process.env.NODE_ENV': JSON.stringify('production')
}),
- new UglifyJsPlugin(),
+ new MiniCssExtractPlugin({
+ filename: '[name].[contenthash].css',
+ chunkFilename: '[id].[contenthash].css'
+ })
]
};
diff --git a/server/package.json b/server/package.json
index a093d0b..237c403 100644
--- a/server/package.json
+++ b/server/package.json
@@ -7,20 +7,20 @@
},
"devDependencies": {},
"dependencies": {
- "react-router-routing-helpers": "1.0.3",
+ "react-router-routing-helpers": "^1.0.3",
"simple-client-request": "file:./ssr/mockupPackages/simpleClientRequest",
- "jquery": "3.2.1",
- "prop-types": "15.6.1",
- "react": "16.3.2",
- "react-dom": "16.3.2",
- "react-router-dom": "4.2.2",
- "body-parser": "1.18.3",
- "cookie-parser": "1.4.3",
- "debug": "4.0.1",
- "express": "4.16.3",
- "express-session": "1.15.6",
- "morgan": "1.9.1",
- "pug": "2.0.3",
- "serve-favicon": "2.5.0"
+ "jquery": "^3.7.1",
+ "prop-types": "^15.8.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "react-router-dom": "^6.22.0",
+ "body-parser": "^1.20.2",
+ "cookie-parser": "^1.4.6",
+ "debug": "^4.3.4",
+ "express": "^4.18.2",
+ "express-session": "^1.17.3",
+ "morgan": "^1.10.0",
+ "pug": "^3.0.2",
+ "serve-favicon": "^2.5.0"
}
}