PR-049111: making mayor change for add support to prefix url.

This commit is contained in:
Alejandro Lembke Barrientos 2023-02-10 21:09:27 +00:00
parent 8ddd290adb
commit e70d0a01ca
17 changed files with 82 additions and 59 deletions

View File

@ -3,4 +3,8 @@ ENV= #Default production
#App Port
PORT= #Default 80
#PUBLIC URL
PUBLIC_URL= #Default /
PUBLIC_URL= #Default 'auto'
#Prefix URL
PREFIX_URL= #Default ''
#ONLY EXACT PATH
ONLY_EXACT_PATH= #Default false

View File

@ -25,13 +25,17 @@ You will need to create a new .env file at the root of the project for global co
This is an exaple of config.
```
#Environment
ENV=development #Default production
ENV= #Default production
#App Port
PORT=3000 #Default 80
PORT= #Default 80
#PUBLIC URL
#PUBLIC_URL= #Default /
PUBLIC_URL= #Default 'auto'
#Prefix URL
PREFIX_URL= #Default ''
#ONLY EXACT PATH
ONLY_EXACT_PATH= #Default false
```
The default environment is production, the app port defauld is 80 and the default public url is "/".
The default environment is production, the app port defauld is 80 and the default public url is "auto", use prefix url if you want a prefix on base url, use exact path to validate if you want to have strict exact paths.
### For Development
In the terminal run:

View File

@ -102,7 +102,7 @@ if(!cleanGitHistory) process.exit(-1);
console.log("Congratulations! You are ready. Follow the following commands to start");
console.log(`cd ${repoName}`);
console.log('Create a .env file with ENV=development(defauld: production), PORT=3000 (default: 80), PUBLIC_URL=your_public_url(optional)(default: /)');
console.log('Create a .env file with ENV=development(defauld: production), PORT=3000 (default: 80), PUBLIC_URL=your_public_url(optional)(default: "auto"), PREFIX_URL=your_prefix_url(optional)(default: ""), ONLY_EXACT_PATH=true(optional)(default: false)');
console.log(`Then you can run: npm start:dev`);
const deleteFolders = isWin ? runCommand(deleteFoldersCommandWindows) : runCommand(deleteFoldersCommand);

View File

@ -1,11 +1,15 @@
export const config = {
ENV: process.env.ENV,
PORT: process.env.PORT,
PUBLIC_URL: process.env.PUBLIC_URL,
};
export const deFaultValues = {
ENV: 'production',
PORT: 3000,
PUBLIC_URL: '/',
}
PORT: 80,
PUBLIC_URL: 'auto',
PREFIX_URL: '',
ONLY_EXACT_PATH: false,
}
export const config = {
ENV: process.env.ENV ? process.env.ENV : deFaultValues.ENV,
PORT: process.env.PORT ? process.env.PORT : deFaultValues.PORT,
PUBLIC_URL: process.env.PUBLIC_URL ? process.env.PUBLIC_URL : deFaultValues.PUBLIC_URL,
PREFIX_URL: process.env.PREFIX_URL ? process.env.PREFIX_URL : deFaultValues.PREFIX_URL,
ONLY_EXACT_PATH: process.env.ONLY_EXACT_PATH ? process.env.ONLY_EXACT_PATH === 'true' : deFaultValues.ONLY_EXACT_PATH,
};

View File

@ -3,6 +3,9 @@ module.exports = {
"testEnvironment": "jsdom",
moduleNameMapper: {
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.ts",
"@components": "<rootDir>/src/frontend/components/",
"@styles": "<rootDir>/src/frontend/styles/",
"@config": "<rootDir>/config/",
"\\.(css|sass|scss|less)$": "identity-obj-proxy"
},
};

View File

@ -1,6 +1,6 @@
{
"name": "@aleleba/create-react-ssr",
"version": "3.5.7",
"version": "3.6.0",
"description": "Starter Kit of server side render of react",
"bin": "./bin/cli.js",
"main": "src/server/index",

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,4 +1,8 @@
declare module "*.svg" {
const content: any;
export default content;
}
}
declare module "@config" {
export const config: any;
}

View File

@ -1,12 +1,11 @@
import React from 'react';
import logo from '../logo.svg';
import './InitialComponent.scss';
import { Link } from "react-router-dom";
const InitialComponent = () => (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<img src="assets/img/logo.svg" className="App-logo" alt="logo" />
<p>
Edit <code>src/frontend/InitialComponent.jsx</code> and save to reload.
</p>

View File

@ -6,7 +6,7 @@ import { Link } from "react-router-dom";
const OtherComponent = () => (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<img src="assets/img/logo.svg" className="App-logo" alt="logo" />
<p>
Edit <code>src/frontend/OtherComponent.jsx</code> and save to reload.
</p>

View File

@ -28,7 +28,7 @@ interface IHot {
accept: any
}
const { ENV } = config;
const { ENV, PREFIX_URL } = config;
const preloadedState = window.__PRELOADED_STATE__;
const store = setStore({ initialState: preloadedState });
@ -41,7 +41,7 @@ if(ENV === 'development') {
const root = createRoot(container);
root.render(
<Provider store={store}>
<Router>
<Router basename={PREFIX_URL}>
<App />
</Router>
</Provider>
@ -51,7 +51,7 @@ if(ENV === 'development') {
// add "const root" to be able to rerender.
ENV === 'production' && hydrateRoot(container,
<Provider store={store}>
<Router>
<Router basename={PREFIX_URL}>
<App />
</Router>
</Provider>,

View File

@ -12,5 +12,4 @@ const INITIAL_COMPONENT = {
element: <InitialComponent />,
};
export default [ INITIAL_COMPONENT, OTHER_COMPONENT ];

View File

@ -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,9 +24,9 @@ import { getHashManifest, haveVendorsCss } from './utilsServer';
//App
import App from '../frontend/components/App';
const { ENV, PORT } = config;
const { ENV, PORT, PREFIX_URL, ONLY_EXACT_PATH } = config;
const routesUrls = routes.map( route => route.path);
const routesUrls = routes.map( route => route.path );
const app = express();
@ -47,6 +47,7 @@ if(ENV === 'development'){
}else{
const baseUrl = __dirname.replace(/\/server(.*)/,'');
const fullURL = `${baseUrl}` ;
console.log(fullURL)
app
.use((req, res, next) => {
if(!req.hashManifest) req.hashManifest = getHashManifest();
@ -102,17 +103,21 @@ const setResponse = (html, preloadedState, manifest) => {
};
const renderApp = (req, res, next) => {
if(routesUrls.includes(req.url)){
const store = setStore({ initialState });
const preloadedState = store.getState();
const html = renderToString(
// @ts-ignore:next-line
<Provider store={store}>
<StaticRouter location={req.url}>
<App />
</StaticRouter>
</Provider>
);
const store = setStore({ initialState });
const preloadedState = store.getState();
const html = renderToString(
// @ts-ignore:next-line
<Provider store={store}>
<StaticRouter location={`${PREFIX_URL}${req.url}`} basename={PREFIX_URL}>
<App />
</StaticRouter>
</Provider>
);
if(ONLY_EXACT_PATH){
if(routesUrls.includes(req.url)){
res.send(setResponse(html, preloadedState, req.hashManifest));
}
} else {
res.send(setResponse(html, preloadedState, req.hashManifest));
}
next();
@ -121,7 +126,6 @@ const renderApp = (req, res, next) => {
app
.get('*', renderApp);
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});

View File

@ -1,7 +1,7 @@
import fs from 'fs';
import { config } from '../../config';
const { ENV } = config;
const { ENV } = config
export const getHashManifest = () => {
try {
@ -17,7 +17,7 @@ export const getHashManifest = () => {
export const haveVendorsCss = (manifest, memoryFs) => {
try {
const baseUrl = __dirname.replace(/\/server(.*)/,'');
const fullURL = `${baseUrl}${manifest ? manifest['vendors.css'] : '/build/assets/vendors.css'}`;
const fullURL = `${baseUrl}${manifest ? `/${manifest['vendors.css']}` : '/build/assets/vendors.css'}`;
ENV === 'production' && fs.readFileSync(fullURL).toString();
ENV === 'development' && memoryFs.readFileSync(fullURL).toString();
return true
@ -25,4 +25,4 @@ export const haveVendorsCss = (manifest, memoryFs) => {
// console.error(err);
return false
}
};
};

View File

@ -21,10 +21,10 @@ const config: Configuration = {
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
alias: {
'@app': path.resolve(__dirname, 'src/frontend/components/App'),
'@components': path.resolve(__dirname, 'src/frontend/components/'),
'@styles': path.resolve(__dirname, 'src/frontend/styles/'),
}
'@config': path.resolve(__dirname, 'config/'),
},
},
module: {
rules: [
@ -58,7 +58,7 @@ const config: Configuration = {
test: fontsAndImagesExtensions,
loader: 'file-loader',
options: {
name: '/assets/[name].[ext]',
name: 'assets/[name].[ext]',
emitFile: false,
},
},

View File

@ -1,6 +1,6 @@
import path from 'path';
import fs from 'fs';
import { deFaultValues } from './config';
import { config as envConfig } from './config';
import webpack, { Configuration } from 'webpack';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
@ -33,18 +33,19 @@ if(fs.existsSync(`${ROOT_DIR}/../public/img`)){
}
const config: Configuration = {
entry: ['webpack-hot-middleware/client?path=/reload_wss&timeout=2000&reload=true&autoConnect=true', `${ROOT_DIR}/../src/frontend/index.tsx`],
entry: [`webpack-hot-middleware/client?path=${envConfig.PREFIX_URL}/reload_wss&timeout=2000&reload=true&autoConnect=true`, `${ROOT_DIR}/../src/frontend/index.tsx`],
output: {
path: BUILD_DIR,
filename: 'assets/app.js',
publicPath: deFaultValues.PUBLIC_URL,
publicPath: envConfig.PUBLIC_URL,
},
resolve: {
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
alias: {
'@components': path.resolve(__dirname, 'src/frontend/components/'),
'@styles': path.resolve(__dirname, 'src/frontend/styles/'),
}
'@components': path.resolve(__dirname, '../src/frontend/components/'),
'@styles': path.resolve(__dirname, '../src/frontend/styles/'),
'@config': path.resolve(__dirname, '../config/'),
},
},
devtool: 'inline-source-map',
mode: 'development',
@ -92,7 +93,7 @@ const config: Configuration = {
}),
new ESLintPlugin(),
new webpack.EnvironmentPlugin({
...deFaultValues,
...envConfig,
}),
new CopyPlugin({
patterns: copyPatterns

View File

@ -1,6 +1,6 @@
import path from 'path';
import fs from 'fs';
import { deFaultValues } from './config';
import { config as envConfig } from './config';
import webpack from 'webpack';
import CompressionWebpackPlugin from 'compression-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
@ -46,13 +46,14 @@ const frontendConfig = {
output: {
path: BUILD_DIR,
filename: 'assets/app-[name]-[fullhash].js',
publicPath: deFaultValues.PUBLIC_URL,
publicPath: envConfig.PUBLIC_URL,
},
resolve: {
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
alias: {
'@components': path.resolve(__dirname, 'src/frontend/components/'),
'@styles': path.resolve(__dirname, 'src/frontend/styles/'),
'@config': path.resolve(__dirname, 'config/'),
}
},
mode: 'production',
@ -100,6 +101,7 @@ const frontendConfig = {
}),
new WebpackManifestPlugin({
fileName: 'assets/manifest-hash.json',
publicPath: envConfig.PREFIX_URL,
}),
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: [
@ -109,7 +111,7 @@ const frontendConfig = {
}),
new ESLintPlugin(),
new webpack.EnvironmentPlugin({
...deFaultValues,
...envConfig,
}),
new CopyPlugin({
patterns: copyPatterns
@ -154,13 +156,14 @@ const serverConfig = {
output: {
path: path.resolve(__dirname, 'build'),
filename: 'server/app-[name].js',
publicPath: deFaultValues.PUBLIC_URL,
publicPath: envConfig.PUBLIC_URL,
},
resolve: {
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
alias: {
'@components': path.resolve(__dirname, 'src/frontend/components/'),
'@styles': path.resolve(__dirname, 'src/frontend/styles/'),
'@config': path.resolve(__dirname, 'config/'),
}
},
mode: 'production',
@ -208,12 +211,10 @@ const serverConfig = {
}),
new WebpackManifestPlugin({
fileName: 'assets/manifest-hash.json',
publicPath: envConfig.PREFIX_URL,
}),
new CleanWebpackPlugin(),
new ESLintPlugin(),
new webpack.EnvironmentPlugin({
...deFaultValues,
}),
new InjectManifest({
swSrc: './service-worker.ts',
swDest: 'service-worker.js',