mirror of
				https://github.com/aleleba/create-react-ssr.git
				synced 2025-10-31 14:10:59 -06:00 
			
		
		
		
	PR-492498: changing some webpack configuration and updating packages.
This commit is contained in:
		| @@ -9,8 +9,8 @@ Tech(Library or Framework) | Version | | ||||
| React (Render Library) | 18.2.0 | ||||
| Redux (Global State Management) | 4.2.0 | ||||
| React Router DOM (Routing) | 6.3.0 | ||||
| Jest (Testing) | 28.1.3 | ||||
| Typescript | 4.7.4 | ||||
| Jest (Testing) | 29.0.1 | ||||
| Typescript | 4.8.2 | ||||
|  | ||||
| ## Setup | ||||
| To create a new project run in the terminal: | ||||
|   | ||||
| @@ -1,6 +1,11 @@ | ||||
| const config = { | ||||
| 	env: process.env.ENV ? process.env.ENV : 'production', | ||||
| 	port: process.env.PORT ? process.env.PORT : 80, | ||||
| export const config = { | ||||
| 	ENV: process.env.ENV, | ||||
| 	PORT: process.env.PORT, | ||||
| 	PUBLIC_URL: process.env.PUBLIC_URL,  | ||||
| }; | ||||
|  | ||||
| export default config; | ||||
| export const deFaultValues = { | ||||
| 	ENV: 'production', | ||||
| 	PORT: 80, | ||||
| 	PUBLIC_URL: '/', | ||||
| } | ||||
							
								
								
									
										2427
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2427
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										35
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,12 +1,12 @@ | ||||
| { | ||||
|   "name": "@aleleba/create-react-ssr", | ||||
|   "version": "3.3.0", | ||||
|   "version": "3.4.0", | ||||
|   "description": "Starter Kit of server side render of react", | ||||
|   "bin": "./bin/cli.js", | ||||
|   "main": "src/server/index", | ||||
|   "scripts": { | ||||
|     "start": "node build/server/app-server.js", | ||||
|     "start:dev": "rm -rf build && webpack --mode=development --config webpack.config.dev.server.ts && node build/server.js", | ||||
|     "start:dev": "rm -rf build && webpack --mode=development --config webpack.config.dev.server.ts", | ||||
|     "build": "webpack-cli --config webpack.config.ts", | ||||
|     "lint": "eslint ./ --ext .js --ext .ts --ext .jsx --ext .tsx", | ||||
|     "lint:fix": "eslint ./ --ext .js --ext .ts --ext .jsx --ext .tsx --fix", | ||||
| @@ -35,7 +35,7 @@ | ||||
|     "asset-require-hook": "^1.2.0", | ||||
|     "dotenv": "^16.0.1", | ||||
|     "express": "^4.18.1", | ||||
|     "helmet": "^5.1.1", | ||||
|     "helmet": "^6.0.0", | ||||
|     "ignore-styles": "^5.0.1", | ||||
|     "react": "^18.2.0", | ||||
|     "react-dom": "^18.2.0", | ||||
| @@ -67,45 +67,46 @@ | ||||
|     "@testing-library/jest-dom": "^5.16.5", | ||||
|     "@testing-library/react": "^13.3.0", | ||||
|     "@testing-library/user-event": "^14.4.3", | ||||
|     "@types/jest": "^28.1.7", | ||||
|     "@types/node": "^18.7.11", | ||||
|     "@types/react": "^18.0.17", | ||||
|     "@types/jest": "^29.0.0", | ||||
|     "@types/node": "^18.7.14", | ||||
|     "@types/react": "^18.0.18", | ||||
|     "@types/react-dom": "^18.0.6", | ||||
|     "@types/webpack": "^5.28.0", | ||||
|     "@types/webpack-hot-middleware": "^2.25.6", | ||||
|     "@types/webpack-node-externals": "^2.5.3", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.34.0", | ||||
|     "@typescript-eslint/parser": "^5.34.0", | ||||
|     "babel-jest": "^28.1.3", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.36.1", | ||||
|     "@typescript-eslint/parser": "^5.36.1", | ||||
|     "babel-jest": "^29.0.1", | ||||
|     "babel-loader": "^8.2.5", | ||||
|     "clean-webpack-plugin": "^4.0.0", | ||||
|     "compression-webpack-plugin": "^10.0.0", | ||||
|     "copy-webpack-plugin": "^11.0.0", | ||||
|     "css-loader": "^6.7.1", | ||||
|     "css-minimizer-webpack-plugin": "^4.0.0", | ||||
|     "eslint": "^8.22.0", | ||||
|     "eslint-plugin-react": "^7.30.1", | ||||
|     "eslint": "^8.23.0", | ||||
|     "eslint-plugin-react": "^7.31.1", | ||||
|     "eslint-webpack-plugin": "^3.2.0", | ||||
|     "file-loader": "^6.2.0", | ||||
|     "identity-obj-proxy": "^3.0.0", | ||||
|     "jest": "^28.1.3", | ||||
|     "jest-environment-jsdom": "^28.1.3", | ||||
|     "jest": "^29.0.1", | ||||
|     "jest-environment-jsdom": "^29.0.1", | ||||
|     "jest-fetch-mock": "^3.0.3", | ||||
|     "mini-css-extract-plugin": "^2.6.1", | ||||
|     "react-refresh": "^0.14.0", | ||||
|     "redux-devtools-extension": "^2.13.9", | ||||
|     "sass": "^1.54.5", | ||||
|     "sass": "^1.54.6", | ||||
|     "sass-loader": "^13.0.2", | ||||
|     "style-loader": "^3.3.1", | ||||
|     "terser-webpack-plugin": "^5.3.5", | ||||
|     "terser-webpack-plugin": "^5.3.6", | ||||
|     "ts-loader": "^9.3.1", | ||||
|     "typescript": "^4.7.4", | ||||
|     "typescript": "^4.8.2", | ||||
|     "url-loader": "^4.1.1", | ||||
|     "webpack-cli": "^4.10.0", | ||||
|     "webpack-dev-middleware": "^5.3.3", | ||||
|     "webpack-dev-server": "^4.10.0", | ||||
|     "webpack-dev-server": "^4.10.1", | ||||
|     "webpack-hot-middleware": "^2.25.2", | ||||
|     "webpack-node-externals": "^3.0.0", | ||||
|     "webpack-shell-plugin-next": "^2.2.2", | ||||
|     "workbox-webpack-plugin": "^6.5.4", | ||||
|     "workbox-window": "^6.5.4" | ||||
|   } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ import { BrowserRouter as Router } from 'react-router-dom'; | ||||
| import { Provider } from 'react-redux'; | ||||
| import { IInitialState } from './reducers/index'; | ||||
| import setStore from './setStore'; | ||||
| import config from '../../config'; | ||||
| import { config } from '../../config'; | ||||
|  | ||||
| import './styles/global.scss'; | ||||
| import App from './components/App'; | ||||
| @@ -28,7 +28,7 @@ interface IHot { | ||||
| 	accept: any | ||||
| } | ||||
|  | ||||
| const { env } = config; | ||||
| const { ENV } = config; | ||||
|  | ||||
| const preloadedState = window.__PRELOADED_STATE__; | ||||
| const store = setStore({ initialState: preloadedState }); | ||||
| @@ -37,7 +37,7 @@ delete window.__PRELOADED_STATE__; | ||||
|  | ||||
| const container = document.getElementById('app')!; | ||||
|  | ||||
| if(env === 'development') { | ||||
| if(ENV === 'development') { | ||||
| 	const root = createRoot(container); | ||||
| 	root.render( | ||||
| 		<Provider store={store}> | ||||
| @@ -49,7 +49,7 @@ if(env === 'development') { | ||||
| } | ||||
|  | ||||
| // add "const root" to be able to rerender. | ||||
| env === 'production' && hydrateRoot(container, | ||||
| ENV === 'production' && hydrateRoot(container, | ||||
| 	<Provider store={store}> | ||||
| 		<Router> | ||||
| 			<App /> | ||||
| @@ -72,7 +72,7 @@ env === 'production' && hydrateRoot(container, | ||||
|     </Provider> | ||||
| ); */ | ||||
|  | ||||
| if((env) && (env === 'production')){ | ||||
| if((ENV) && (ENV === 'production')){ | ||||
| 	serviceWorkerRegistration(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,18 +2,18 @@ | ||||
| import { legacy_createStore as createStore} from 'redux'; //, applyMiddleware | ||||
| // import { Provider } from 'react-redux'; | ||||
| import { composeWithDevTools as composeWithDevToolsWeb } from 'redux-devtools-extension'; | ||||
| import config from '../../config'; | ||||
| import { config } from '../../config'; | ||||
| import reducer, { IInitialState } from './reducers'; | ||||
|  | ||||
|  | ||||
| const { env } = config; | ||||
| const { ENV } = config; | ||||
|  | ||||
| const composeEnhancers = composeWithDevToolsWeb({ | ||||
| 	// Specify here name, actionsBlacklist, actionsCreators and other options | ||||
| }); | ||||
|  | ||||
| const setStore = ({ initialState }: { initialState: IInitialState | undefined }) => { | ||||
| 	const store = env === 'development' ? createStore( | ||||
| 	const store = ENV === 'development' ? createStore( | ||||
| 		reducer, | ||||
| 		initialState, | ||||
| 		composeEnhancers(), | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| import express from 'express'; | ||||
| import webpack from 'webpack'; | ||||
| import helmet from 'helmet'; | ||||
| import config from '../../config'; | ||||
| import { config } from '../../config'; | ||||
|  | ||||
| //Dependencies of HotReloading | ||||
| import webpackConfig from '../../webpack.config.dev'; | ||||
| @@ -24,7 +24,7 @@ import { getHashManifest, haveVendorsCss } from './utilsServer'; | ||||
| //App | ||||
| import App from '../frontend/components/App'; | ||||
|  | ||||
| const { env, port } = config; | ||||
| const { ENV, PORT } = config; | ||||
|  | ||||
| const routesUrls = routes.map( route => route.path); | ||||
|  | ||||
| @@ -32,7 +32,7 @@ const app = express(); | ||||
|  | ||||
| // @ts-ignore:next-line | ||||
| const compiler = webpack(webpackConfig); | ||||
| if(env === 'development'){ | ||||
| if(ENV === 'development'){ | ||||
| 	const serverConfig = {  | ||||
| 		serverSideRender: true, | ||||
| 		publicPath: webpackConfig.output?.publicPath, | ||||
| @@ -122,6 +122,6 @@ app | ||||
| 	.get('*', renderApp); | ||||
|  | ||||
|  | ||||
| app.listen(port, () => { | ||||
| 	console.log(`Server running on port ${port}`); | ||||
| app.listen(PORT, () => { | ||||
| 	console.log(`Server running on port ${PORT}`); | ||||
| }); | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import fs from 'fs'; | ||||
| import config from '../../config'; | ||||
| import { config } from '../../config'; | ||||
|  | ||||
| const { env } = config | ||||
| const { ENV } = config; | ||||
|  | ||||
| export const getHashManifest = () => { | ||||
| 	try { | ||||
| @@ -18,8 +18,8 @@ export const haveVendorsCss = (manifest, memoryFs) => { | ||||
| 	try { | ||||
| 		const baseUrl = __dirname.replace(/\/server(.*)/,''); | ||||
| 		const fullURL = `${baseUrl}${manifest ? manifest['vendors.css'] : '/build/assets/vendors.css'}`; | ||||
| 		env === 'production' && fs.readFileSync(fullURL).toString(); | ||||
| 		env === 'development' && memoryFs.readFileSync(fullURL).toString(); | ||||
| 		ENV === 'production' && fs.readFileSync(fullURL).toString(); | ||||
| 		ENV === 'development' && memoryFs.readFileSync(fullURL).toString(); | ||||
| 		return true | ||||
| 	}catch(err){ | ||||
| 		// console.error(err); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import MiniCssExtractPlugin from 'mini-css-extract-plugin'; | ||||
| import webpackNodeExternals from 'webpack-node-externals'; | ||||
| import WebpackShellPluginNext from 'webpack-shell-plugin-next'; | ||||
| import path from 'path'; | ||||
| import { Configuration } from 'webpack'; | ||||
| const ROOT_DIR = path.resolve(__dirname); | ||||
| @@ -57,7 +58,7 @@ const config: Configuration = { | ||||
|         test: fontsAndImagesExtensions, | ||||
|         loader: 'file-loader', | ||||
| 				options: { | ||||
| 					name: '/assets/media/[name].[ext]', | ||||
| 					name: '/assets/[name].[ext]', | ||||
|           emitFile: false, | ||||
| 				}, | ||||
|       }, | ||||
| @@ -82,6 +83,13 @@ const config: Configuration = { | ||||
|     new MiniCssExtractPlugin({ | ||||
|         filename: 'assets/app.css', | ||||
|     }), | ||||
|     new WebpackShellPluginNext({ | ||||
| 			onBuildEnd: { | ||||
| 				scripts: ['node build/server.js'], | ||||
| 				blocking: false, | ||||
| 				parallel: true | ||||
| 			} | ||||
| 		}) | ||||
|   ], | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -1,24 +1,43 @@ | ||||
| import path from 'path'; | ||||
| import * as dotenv from 'dotenv'; | ||||
| import fs from 'fs'; | ||||
| import { deFaultValues } from './config'; | ||||
| import webpack, { Configuration } from 'webpack'; | ||||
| import MiniCssExtractPlugin from 'mini-css-extract-plugin'; | ||||
| import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; | ||||
| import ESLintPlugin from 'eslint-webpack-plugin'; | ||||
| import CopyPlugin from 'copy-webpack-plugin'; | ||||
|  | ||||
| const dotEnvToParse = dotenv.config(); | ||||
|  | ||||
| const ROOT_DIR = path.resolve(__dirname); | ||||
| const resolvePath = (...args: string[]) => path.resolve(ROOT_DIR, ...args); | ||||
| const BUILD_DIR = resolvePath('build'); | ||||
| const PUBLIC_URL = process.env.PUBLIC_URL || '/'; | ||||
|  | ||||
| const copyPatterns = [ | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/../public/manifest.json`, to: '', | ||||
| 	}, | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/../public/favicon.ico`, to: '', | ||||
| 	}, | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/../public/logo192.png`, to: '', | ||||
| 	}, | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/../public/logo512.png`, to: '', | ||||
| 	}, | ||||
| ] | ||||
|  | ||||
| if(fs.existsSync(`${ROOT_DIR}/../public/img`)){ | ||||
| 	copyPatterns.push({ | ||||
| 		from: `${ROOT_DIR}/../public/img`, to: 'assets/img',  | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| const config: Configuration = { | ||||
| 	entry: ['webpack-hot-middleware/client?path=/reload_wss&timeout=2000&reload=true&autoConnect=true', `${ROOT_DIR}/../src/frontend/index.tsx`], | ||||
| 	output: { | ||||
| 		path: BUILD_DIR, | ||||
| 		filename: 'assets/app.js', | ||||
| 		publicPath: PUBLIC_URL, | ||||
| 		publicPath: deFaultValues.PUBLIC_URL, | ||||
| 	}, | ||||
| 	resolve: { | ||||
| 		extensions: ['.js', '.jsx','.ts','.tsx', '.json'], | ||||
| @@ -52,7 +71,7 @@ const config: Configuration = { | ||||
| 				test: /\.(png|jpg|jpeg|gif|svg|ico|mp4|avi|ttf|otf|eot|woff|woff2|pdf)$/, | ||||
| 				loader: 'file-loader', | ||||
| 				options: { | ||||
| 					name: 'assets/media/[name].[ext]', | ||||
| 					name: 'assets/[name].[ext]', | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| @@ -72,25 +91,11 @@ const config: Configuration = { | ||||
| 			filename: 'assets/[name].css', | ||||
| 		}), | ||||
| 		new ESLintPlugin(), | ||||
| 		new webpack.DefinePlugin({ | ||||
| 			'process.env': JSON.stringify(dotEnvToParse.parsed), | ||||
| 			'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL), | ||||
| 		new webpack.EnvironmentPlugin({ | ||||
| 			...deFaultValues, | ||||
| 		}), | ||||
| 		new CopyPlugin({ | ||||
| 			patterns: [ | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/../public/manifest.json`, to: '', | ||||
| 				}, | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/../public/favicon.ico`, to: '', | ||||
| 				}, | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/../public/logo192.png`, to: '', | ||||
| 				}, | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/../public/logo512.png`, to: '', | ||||
| 				}, | ||||
| 			] | ||||
| 			patterns: copyPatterns | ||||
| 		}), | ||||
| 	], | ||||
| 	optimization: { | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| import path  from 'path'; | ||||
| import * as dotenv from 'dotenv'; | ||||
| import fs from 'fs'; | ||||
| import { deFaultValues } from './config'; | ||||
| import webpack from 'webpack'; | ||||
| import CompressionWebpackPlugin from 'compression-webpack-plugin'; | ||||
| import MiniCssExtractPlugin from 'mini-css-extract-plugin'; | ||||
| @@ -10,14 +11,33 @@ import { CleanWebpackPlugin } from 'clean-webpack-plugin'; | ||||
| import ESLintPlugin from 'eslint-webpack-plugin'; | ||||
| import CopyPlugin from 'copy-webpack-plugin'; | ||||
|  | ||||
| const dotEnvToParse = dotenv.config(); | ||||
|  | ||||
| const ROOT_DIR = path.resolve(__dirname); | ||||
| const resolvePath = (...args) => path.resolve(ROOT_DIR, ...args); | ||||
| const BUILD_DIR = resolvePath('build'); | ||||
| const { InjectManifest } = require('workbox-webpack-plugin'); | ||||
| const nodeExternals = require('webpack-node-externals'); | ||||
| const PUBLIC_URL = process.env.PUBLIC_URL || '/'; | ||||
|  | ||||
| const copyPatterns = [ | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/public/manifest.json`, to: '', | ||||
| 	}, | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/public/favicon.ico`, to: '', | ||||
| 	}, | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/public/logo192.png`, to: '', | ||||
| 	}, | ||||
| 	{ | ||||
| 		from: `${ROOT_DIR}/public/logo512.png`, to: '', | ||||
| 	}, | ||||
| 	 | ||||
| ] | ||||
|  | ||||
| if(fs.existsSync(`${ROOT_DIR}/public/img`)){ | ||||
| 	copyPatterns.push({ | ||||
| 		from: `${ROOT_DIR}/public/img`, to: 'assets/img',  | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| const frontendConfig = { | ||||
| 	entry: { | ||||
| @@ -26,7 +46,7 @@ const frontendConfig = { | ||||
| 	output: { | ||||
| 		path: BUILD_DIR, | ||||
| 		filename: 'assets/app-[name]-[fullhash].js', | ||||
| 		publicPath: PUBLIC_URL, | ||||
| 		publicPath: deFaultValues.PUBLIC_URL, | ||||
| 	}, | ||||
| 	resolve: { | ||||
| 		extensions: ['.js', '.jsx','.ts','.tsx', '.json'], | ||||
| @@ -57,7 +77,7 @@ const frontendConfig = { | ||||
| 				test: /\.(png|jpg|jpeg|gif|svg|ico|mp4|avi|ttf|otf|eot|woff|woff2|pdf)$/, | ||||
| 				loader: 'file-loader', | ||||
| 				options: { | ||||
| 					name: 'assets/media/[name].[ext]', | ||||
| 					name: 'assets/[name].[ext]', | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| @@ -88,25 +108,11 @@ const frontendConfig = { | ||||
| 			], | ||||
| 		}), | ||||
| 		new ESLintPlugin(), | ||||
| 		new webpack.DefinePlugin({ | ||||
| 			'process.env': JSON.stringify(dotEnvToParse.parsed), | ||||
| 			'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL), | ||||
| 		new webpack.EnvironmentPlugin({ | ||||
| 			...deFaultValues, | ||||
| 		}), | ||||
| 		new CopyPlugin({ | ||||
| 			patterns: [ | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/public/manifest.json`, to: '', | ||||
| 				}, | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/public/favicon.ico`, to: '', | ||||
| 				}, | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/public/logo192.png`, to: '', | ||||
| 				}, | ||||
| 				{ | ||||
| 					from: `${ROOT_DIR}/public/logo512.png`, to: '', | ||||
| 				}, | ||||
| 			] | ||||
| 			patterns: copyPatterns | ||||
| 		}), | ||||
| 		new InjectManifest({ | ||||
| 			swSrc: './service-worker.ts', | ||||
| @@ -148,7 +154,7 @@ const serverConfig = { | ||||
| 	output: { | ||||
| 		path: path.resolve(__dirname, 'build'), | ||||
| 		filename: 'server/app-[name].js', | ||||
| 		publicPath: PUBLIC_URL, | ||||
| 		publicPath: deFaultValues.PUBLIC_URL, | ||||
| 	}, | ||||
| 	resolve: { | ||||
| 		extensions: ['.js', '.jsx','.ts','.tsx', '.json'], | ||||
| @@ -179,7 +185,7 @@ const serverConfig = { | ||||
| 				test: /\.(png|jpg|jpeg|gif|svg|ico|mp4|avi|ttf|otf|eot|woff|woff2|pdf)$/, | ||||
| 				loader: 'file-loader', | ||||
| 				options: { | ||||
| 					name: 'assets/media/[name].[ext]', | ||||
| 					name: 'assets/[name].[ext]', | ||||
| 				}, | ||||
| 			}, | ||||
| 			{ | ||||
| @@ -205,9 +211,8 @@ const serverConfig = { | ||||
| 		}), | ||||
| 		new CleanWebpackPlugin(), | ||||
| 		new ESLintPlugin(), | ||||
| 		new webpack.DefinePlugin({ | ||||
| 			'process.env': JSON.stringify(dotEnvToParse.parsed), | ||||
| 			'process.env.PUBLIC_URL': JSON.stringify(PUBLIC_URL), | ||||
| 		new webpack.EnvironmentPlugin({ | ||||
| 			...deFaultValues, | ||||
| 		}), | ||||
| 		new InjectManifest({ | ||||
| 			swSrc: './service-worker.ts', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user