First commit creating version 0.0.1
This commit is contained in:
commit
d4f2474436
7
.babelrc
Normal file
7
.babelrc
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"presets": [
|
||||
["@babel/preset-env", {"targets": {"node": "current"}}],
|
||||
"@babel/preset-react",
|
||||
"@babel/preset-typescript"
|
||||
]
|
||||
}
|
10
.env.example
Normal file
10
.env.example
Normal file
@ -0,0 +1,10 @@
|
||||
#Environment
|
||||
ENV= #Default production
|
||||
#App Port
|
||||
PORT= #Default 80
|
||||
#PUBLIC URL
|
||||
PUBLIC_URL= #Default 'auto'
|
||||
#Prefix URL
|
||||
PREFIX_URL= #Default ''
|
||||
#ONLY EXACT PATH
|
||||
ONLY_EXACT_PATH= #Default false
|
10
.eslintignore
Normal file
10
.eslintignore
Normal file
@ -0,0 +1,10 @@
|
||||
#Build
|
||||
build
|
||||
#Webpack
|
||||
webpack.config.ts
|
||||
webpack.config.dev.ts
|
||||
webpack.config.dev.server.ts
|
||||
webpack.cy.config.ts
|
||||
#Service Worker
|
||||
service-worker.ts
|
||||
serviceWorkerRegistration.ts
|
52
.eslintrc.js
Normal file
52
.eslintrc.js
Normal file
@ -0,0 +1,52 @@
|
||||
module.exports = {
|
||||
'env': {
|
||||
'browser': true,
|
||||
'node': true,
|
||||
'es2021': true
|
||||
},
|
||||
'extends': [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:@typescript-eslint/recommended'
|
||||
],
|
||||
'parser': '@typescript-eslint/parser',
|
||||
'parserOptions': {
|
||||
'ecmaFeatures': {
|
||||
'jsx': true
|
||||
},
|
||||
'ecmaVersion': 'latest',
|
||||
'sourceType': 'module'
|
||||
},
|
||||
'plugins': [
|
||||
'react',
|
||||
'@typescript-eslint'
|
||||
],
|
||||
'rules': {
|
||||
'indent': [
|
||||
'error',
|
||||
'tab'
|
||||
],
|
||||
'linebreak-style': [
|
||||
'error',
|
||||
'unix'
|
||||
],
|
||||
'quotes': [
|
||||
'error',
|
||||
'single'
|
||||
],
|
||||
'semi': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'eol-last': [
|
||||
'error',
|
||||
'always'
|
||||
],
|
||||
'@typescript-eslint/no-var-requires': 0,
|
||||
},
|
||||
'settings': {
|
||||
'react': {
|
||||
'version': 'detect',
|
||||
}
|
||||
}
|
||||
};
|
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
#node_modules ignore
|
||||
node_modules
|
||||
#.envs
|
||||
.env
|
||||
#builds
|
||||
build
|
||||
src/server/main
|
||||
src/server/react-server
|
||||
src/server/web/dist
|
||||
src/server/web/utils
|
||||
#cypress
|
||||
cypress/videos
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Alejandro Lembke Barrientos
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
11
PRNameGenerator.ts
Normal file
11
PRNameGenerator.ts
Normal file
@ -0,0 +1,11 @@
|
||||
const PRName = function () {
|
||||
let ID = '';
|
||||
// let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
const characters = '0123456789';
|
||||
for ( let i = 0; i < 6; i++ ) {
|
||||
ID += characters.charAt(Math.floor(Math.random() * 10));
|
||||
}
|
||||
return 'PR-'+ID;
|
||||
};
|
||||
|
||||
console.log(PRName());
|
78
README.md
Normal file
78
README.md
Normal file
@ -0,0 +1,78 @@
|
||||
# Create React SSR
|
||||
|
||||
This project aims to have a starter kit for creating a new React app with Server Side Rendering and tools that generally go along with it.
|
||||
|
||||
It is not a project like create-react-app, create-react-app is used as a starter kit that handles all your scripts underneath, this is a project for developers who want more control over their application.
|
||||
|
||||
Tech(Library or Framework) | Version |
|
||||
--- | --- |
|
||||
React (Render Library) | 18.2.0
|
||||
Redux (Global State Management) | 4.2.1
|
||||
React Router DOM (Routing) | 6.15.0
|
||||
Jest (Testing) | 29.6.4
|
||||
Cypress (E2E Testing) | 13.1.0
|
||||
Typescript | 5.2.2
|
||||
|
||||
## Setup
|
||||
To create a new project run in the terminal:
|
||||
```
|
||||
npx @aleleba/create-react-ssr app-name
|
||||
```
|
||||
Then run:
|
||||
```
|
||||
cd app-name
|
||||
```
|
||||
You will need to create a new .env file at the root of the project for global config.
|
||||
This is an exaple of config.
|
||||
```
|
||||
#Environment
|
||||
ENV= #Default production
|
||||
#App Port
|
||||
PORT= #Default 80
|
||||
#PUBLIC URL
|
||||
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 "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:
|
||||
```
|
||||
npm run start:dev
|
||||
```
|
||||
The ENV enviroment variable should be "development" and choose the port of your preference with the enviroment variable PORT.
|
||||
|
||||
You will find the root component on:
|
||||
```
|
||||
scr/frontend/components/App.tsx
|
||||
```
|
||||
You will find the Initial Component on:
|
||||
```
|
||||
scr/frontend/components/InitialComponent.tsx
|
||||
```
|
||||
|
||||
The manage of the routes you should find on:
|
||||
```
|
||||
scr/routes
|
||||
```
|
||||
It is using "useRoutes" hook for working, more information for this here: (https://reactrouter.com/docs/en/v6/api#useroutes)
|
||||
|
||||
This will start the app in development mode, also it have Hot Reloading!
|
||||
Enjoy coding!
|
||||
|
||||
### For Production
|
||||
In the terminal run:
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
It will create a build folder and run:
|
||||
```
|
||||
npm start
|
||||
```
|
||||
This will start the app.
|
||||
|
||||
## Cheers
|
||||
Hope you enjoy this proyect! Sincerely Alejandro Lembke Barrientos.
|
17
config/index.ts
Normal file
17
config/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
export const deFaultValues = {
|
||||
ENV: 'production',
|
||||
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,
|
||||
};
|
||||
|
||||
export default config;
|
24
cypress.config.ts
Normal file
24
cypress.config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { defineConfig } from 'cypress';
|
||||
import webpackConfig from './webpack.cy.config';
|
||||
|
||||
export default defineConfig({
|
||||
env: {},
|
||||
e2e: {
|
||||
/*setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
},*/
|
||||
baseUrl: 'http://localhost:3000',
|
||||
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
|
||||
experimentalRunAllSpecs: true,
|
||||
},
|
||||
component: {
|
||||
specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}',
|
||||
devServer: {
|
||||
framework: 'react',
|
||||
bundler: 'webpack',
|
||||
webpackConfig: webpackConfig,
|
||||
},
|
||||
viewportWidth: 1280,
|
||||
viewportHeight: 720,
|
||||
}
|
||||
});
|
19
jest.config.js
Normal file
19
jest.config.js
Normal file
@ -0,0 +1,19 @@
|
||||
const { pathsToModuleNameMapper } = require('ts-jest');
|
||||
const { compilerOptions } = require('./tsconfig');
|
||||
|
||||
const aliases = pathsToModuleNameMapper(compilerOptions.paths, {
|
||||
prefix: '<rootDir>'
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
setupFilesAfterEnv: ['<rootDir>/setupTest.ts'],
|
||||
testPathIgnorePatterns: ['/node_modules/', '\\.cy.(js|jsx|ts|tsx)$'],
|
||||
testEnvironment: 'jsdom',
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
|
||||
modulePathIgnorePatterns: ['<rootDir>/cypress/'],
|
||||
moduleNameMapper: {
|
||||
...aliases,
|
||||
'\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/src/__mocks__/fileMock.ts',
|
||||
'\\.(css|sass|scss|less)$': 'identity-obj-proxy',
|
||||
}
|
||||
};
|
122
package.json
Normal file
122
package.json
Normal file
@ -0,0 +1,122 @@
|
||||
{
|
||||
"name": "@aleleba/create-react-go-ssr",
|
||||
"version": "0.0.1",
|
||||
"description": "Starter Kit of server side render of react",
|
||||
"bin": "./bin/cli.js",
|
||||
"main": "src/server/index",
|
||||
"scripts": {
|
||||
"start": "webpack watch --config webpack.config.ts",
|
||||
"buildTsxToString": "webpack --config webpack.config.convert.ts",
|
||||
"start:dev": "rm -rf build && webpack --mode=development --config webpack.config.dev.server.ts",
|
||||
"start:dev-win": "(if exist build rmdir /s /Q 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",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"check-updates": "npx npm-check-updates -u && npm i",
|
||||
"cy:open": "npx cypress open",
|
||||
"cy:run": "cypress run",
|
||||
"cy:run-component": "cypress run --headless --component"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/aleleba/create-react-ssr.git"
|
||||
},
|
||||
"keywords": [
|
||||
"create react app",
|
||||
"react",
|
||||
"ssr",
|
||||
"typescript",
|
||||
"redux"
|
||||
],
|
||||
"author": "Alejandro Lembke Barrientos",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/aleleba/create-react-ssr/issues"
|
||||
},
|
||||
"homepage": "https://github.com/aleleba/create-react-ssr#readme",
|
||||
"dependencies": {
|
||||
"@babel/register": "^7.22.15",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"helmet": "^7.0.0",
|
||||
"history": "^5.3.0",
|
||||
"ignore-styles": "^5.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-redux": "^8.1.2",
|
||||
"react-router-dom": "^6.15.0",
|
||||
"react-router-hash-link": "^2.4.3",
|
||||
"redux": "^4.2.1",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-manifest-plugin": "^5.0.0",
|
||||
"workbox-background-sync": "^7.0.0",
|
||||
"workbox-broadcast-update": "^7.0.0",
|
||||
"workbox-cacheable-response": "^7.0.0",
|
||||
"workbox-core": "^7.0.0",
|
||||
"workbox-expiration": "^7.0.0",
|
||||
"workbox-google-analytics": "^7.0.0",
|
||||
"workbox-navigation-preload": "^7.0.0",
|
||||
"workbox-precaching": "^7.0.0",
|
||||
"workbox-range-requests": "^7.0.0",
|
||||
"workbox-routing": "^7.0.0",
|
||||
"workbox-strategies": "^7.0.0",
|
||||
"workbox-streams": "^7.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.17",
|
||||
"@babel/preset-env": "^7.22.15",
|
||||
"@babel/preset-react": "^7.22.15",
|
||||
"@babel/preset-typescript": "^7.22.15",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
|
||||
"@redux-devtools/extension": "^3.2.5",
|
||||
"@testing-library/jest-dom": "^6.1.3",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/jest": "^29.5.4",
|
||||
"@types/node": "^20.6.0",
|
||||
"@types/react": "^18.2.21",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/webpack": "^5.28.2",
|
||||
"@types/webpack-hot-middleware": "^2.25.6",
|
||||
"@types/webpack-node-externals": "^3.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.6.0",
|
||||
"@typescript-eslint/parser": "^6.6.0",
|
||||
"babel-jest": "^29.6.4",
|
||||
"babel-loader": "^9.1.3",
|
||||
"clean-webpack-plugin": "^4.0.0",
|
||||
"compression-webpack-plugin": "^10.0.0",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.8.1",
|
||||
"css-minimizer-webpack-plugin": "^5.0.1",
|
||||
"cypress": "^13.1.0",
|
||||
"eslint": "^8.49.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-webpack-plugin": "^4.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "^5.5.3",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^29.6.4",
|
||||
"jest-environment-jsdom": "^29.6.4",
|
||||
"jest-fetch-mock": "^3.0.3",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"react-refresh": "^0.14.0",
|
||||
"resolve-ts-aliases": "^1.0.1",
|
||||
"sass": "^1.66.1",
|
||||
"sass-loader": "^13.3.2",
|
||||
"style-loader": "^3.3.3",
|
||||
"terser-webpack-plugin": "^5.3.9",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.2.2",
|
||||
"url-loader": "^4.1.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-middleware": "^6.1.1",
|
||||
"webpack-dev-server": "^4.15.1",
|
||||
"webpack-hot-middleware": "^2.25.4",
|
||||
"webpack-node-externals": "^3.0.0",
|
||||
"webpack-shell-plugin-next": "^2.3.1",
|
||||
"workbox-webpack-plugin": "^7.0.0",
|
||||
"workbox-window": "^7.0.0"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
1
public/img/logo.svg
Normal file
1
public/img/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
After Width: | Height: | Size: 2.6 KiB |
22
public/index.html
Normal file
22
public/index.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!-- ${manifestJson} -->
|
||||
<link href="assets/frontend.css" rel="stylesheet" type="text/css"></link>
|
||||
|
||||
<title>App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- <script>
|
||||
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
|
||||
</script> -->
|
||||
<script src="assets/app-frontend.js" type="text/javascript"></script>
|
||||
<script src="assets/vendor-vendors.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
BIN
public/logo192.png
Normal file
BIN
public/logo192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
BIN
public/logo512.png
Normal file
BIN
public/logo512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.4 KiB |
25
public/manifest.json
Normal file
25
public/manifest.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "React App SSR Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
61
service-worker.ts
Normal file
61
service-worker.ts
Normal file
@ -0,0 +1,61 @@
|
||||
// This service worker can be customized!
|
||||
// See https://developers.google.com/web/tools/workbox/modules
|
||||
// for the list of available Workbox modules, or add any other
|
||||
// code you'd like.
|
||||
// You can also remove this file if you'd prefer not to use a
|
||||
// service worker, and the Workbox build step will be skipped.
|
||||
|
||||
import { clientsClaim } from 'workbox-core';
|
||||
import { ExpirationPlugin } from 'workbox-expiration';
|
||||
import { precacheAndRoute } from 'workbox-precaching'; //createHandlerBoundToURL
|
||||
import { registerRoute } from 'workbox-routing';
|
||||
import { StaleWhileRevalidate, NetworkFirst } from 'workbox-strategies';
|
||||
|
||||
clientsClaim();
|
||||
|
||||
// This allows the web app to trigger skipWaiting via
|
||||
// @ts-ignore:next-line
|
||||
self.skipWaiting();
|
||||
|
||||
// Precache all of the assets generated by your build process.
|
||||
// Their URLs are injected into the manifest variable below.
|
||||
// This variable must be present somewhere in your service worker file,
|
||||
// even if you decide not to use precaching. See https://cra.link/PWA
|
||||
// @ts-ignore:next-line
|
||||
precacheAndRoute(self.__WB_MANIFEST);
|
||||
|
||||
// An example runtime caching route for requests that aren't handled by the
|
||||
// precache, in this case same-origin .png requests like those from in public/
|
||||
registerRoute(
|
||||
// Add in any other file extensions or routing criteria as needed.
|
||||
({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
|
||||
new StaleWhileRevalidate({
|
||||
cacheName: 'images',
|
||||
plugins: [
|
||||
// Ensure that once this runtime cache reaches a maximum size the
|
||||
// least-recently used images are removed.
|
||||
new ExpirationPlugin({ maxEntries: 50 }),
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
// Any other custom service worker logic can go here.
|
||||
|
||||
//Estrategy for Default. It should be at the end.
|
||||
registerRoute(/^https?.*/, new NetworkFirst(), 'GET');
|
||||
|
||||
//Wait for Notification.
|
||||
self.addEventListener('push', function (e) {
|
||||
|
||||
// @ts-ignore:next-line
|
||||
const data = e.data.json();
|
||||
|
||||
// @ts-ignore:next-line
|
||||
registration.showNotification(data.title, {
|
||||
body: data.message,
|
||||
icon: 'favicon.ico'
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
console.log('hello from service-worker.js the new one.');
|
21
serviceWorkerRegistration.ts
Normal file
21
serviceWorkerRegistration.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Workbox } from 'workbox-window';
|
||||
import packageJson from './package.json';
|
||||
|
||||
const serviceWorkerRegistration = () => {
|
||||
if ('serviceWorker' in navigator) {
|
||||
const wb = new Workbox('service-worker.js');
|
||||
|
||||
wb.addEventListener('installed', event => {
|
||||
if(event.isUpdate){
|
||||
if(confirm('New app update is avaible, Click Ok to refresh')){
|
||||
window.location.reload();
|
||||
};
|
||||
console.log(`Se actualiza la app a version ${packageJson.version}`);
|
||||
};
|
||||
});
|
||||
|
||||
wb.register();
|
||||
};
|
||||
};
|
||||
|
||||
export default serviceWorkerRegistration;
|
20
setupTest.ts
Normal file
20
setupTest.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
//import fetch Mock
|
||||
import fetchMock from 'jest-fetch-mock';
|
||||
fetchMock.enableMocks();
|
||||
|
||||
//Fixing Pollyfill for react-slick
|
||||
window.matchMedia =
|
||||
window.matchMedia ||
|
||||
function() {
|
||||
return {
|
||||
matches: false,
|
||||
addListener: () => {/**/},
|
||||
removeListener: () => {/**/}
|
||||
};
|
||||
};
|
9
src/@types/express/index.d.ts
vendored
Normal file
9
src/@types/express/index.d.ts
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
import * as express from "express"
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
interface Request {
|
||||
hashManifest?: Record<string,any>
|
||||
}
|
||||
}
|
||||
}
|
4
src/@types/index.d.ts
vendored
Normal file
4
src/@types/index.d.ts
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
declare module "*.svg" {
|
||||
const content: any;
|
||||
export default content;
|
||||
}
|
9
src/frontend/actions/index.ts
Normal file
9
src/frontend/actions/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import test, { TTest } from './testAction';
|
||||
|
||||
export type TAction = TTest
|
||||
|
||||
const actions = {
|
||||
test
|
||||
}
|
||||
|
||||
export default actions
|
25
src/frontend/actions/testAction.ts
Normal file
25
src/frontend/actions/testAction.ts
Normal file
@ -0,0 +1,25 @@
|
||||
export enum ActionTypesTest {
|
||||
ChangeHello = 'CHANGE_HELLO'
|
||||
}
|
||||
|
||||
export interface IChangeHello {
|
||||
type: ActionTypesTest.ChangeHello
|
||||
payload: IChangeHelloPayload
|
||||
}
|
||||
|
||||
export interface IChangeHelloPayload {
|
||||
hello: any | undefined
|
||||
}
|
||||
|
||||
export type TTest = IChangeHello
|
||||
|
||||
const changeHello = (payload: string) => ({
|
||||
type: ActionTypesTest.ChangeHello,
|
||||
payload
|
||||
})
|
||||
|
||||
const actions = {
|
||||
changeHello
|
||||
}
|
||||
|
||||
export default actions
|
17
src/frontend/components/App.tsx
Normal file
17
src/frontend/components/App.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PrincipalRoutes from './PrincipalRoutes';
|
||||
|
||||
const App = () => {
|
||||
useEffect(() => {
|
||||
const ws = new WebSocket('wss://xs70kvlc-3000.use.devtunnels.ms/ws');
|
||||
ws.onmessage = (event) => {
|
||||
if (event.data === 'reload') {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return <PrincipalRoutes />;
|
||||
};
|
||||
|
||||
export default App;
|
38
src/frontend/components/InitialComponent.scss
Normal file
38
src/frontend/components/InitialComponent.scss
Normal file
@ -0,0 +1,38 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
25
src/frontend/components/InitialComponent.tsx
Normal file
25
src/frontend/components/InitialComponent.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import './InitialComponent.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const InitialComponent = () => (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src="assets/img/logo.svg" className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/frontend/InitialComponent.jsx</code> and save to reload.
|
||||
</p>
|
||||
<a
|
||||
className="App-link"
|
||||
href="https://reactjs.org"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Learn React
|
||||
</a>
|
||||
<Link className="App-link" to="/other-component">Other Component</Link>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default InitialComponent;
|
18
src/frontend/components/OtherComponent.tsx
Normal file
18
src/frontend/components/OtherComponent.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
// import logo from '../logo.svg';
|
||||
import './InitialComponent.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const OtherComponent = () => (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src="assets/img/logo.svg" className="App-logo" alt="logo" />
|
||||
<p>
|
||||
Edit <code>src/frontend/OtherComponent.jsx</code> and save to reload.
|
||||
</p>
|
||||
<Link className="App-link" to="/">Initial Component</Link>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default OtherComponent;
|
11
src/frontend/components/PrincipalRoutes.tsx
Normal file
11
src/frontend/components/PrincipalRoutes.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
//Router
|
||||
import { useRoutes } from 'react-router-dom';
|
||||
//Routes
|
||||
import routes from '../../routes';
|
||||
|
||||
const PrincipalRoutes = () => {
|
||||
let element = useRoutes(routes);
|
||||
return element;
|
||||
};
|
||||
|
||||
export default PrincipalRoutes;
|
16
src/frontend/components/__tests__/App.test.cy.tsx
Normal file
16
src/frontend/components/__tests__/App.test.cy.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import { ProviderMock } from '@mocks';
|
||||
import App from '@components/App';
|
||||
|
||||
describe('Testing Card Component', () => {
|
||||
beforeEach(() => {
|
||||
cy.mount(
|
||||
<ProviderMock>
|
||||
<App />
|
||||
</ProviderMock>
|
||||
);
|
||||
});
|
||||
it('Show Text', () => {
|
||||
cy.get('p').contains('Edit src/frontend/InitialComponent.jsx and save to reload.');
|
||||
});
|
||||
});
|
23
src/frontend/components/__tests__/App.test.tsx
Normal file
23
src/frontend/components/__tests__/App.test.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { ProviderMock } from '@mocks';
|
||||
import App from '@components/App';
|
||||
|
||||
describe('<App/> Component', () => {
|
||||
beforeEach(() => {
|
||||
fetchMock.resetMocks();
|
||||
});
|
||||
|
||||
it('Should render root <App /> Component', async () => {
|
||||
fetchMock.mockResponseOnce(JSON.stringify({
|
||||
//First Data Fetch
|
||||
data: 'data'
|
||||
}));
|
||||
|
||||
render(
|
||||
<ProviderMock>
|
||||
<App />
|
||||
</ProviderMock>
|
||||
)
|
||||
})
|
||||
})
|
16
src/frontend/converter/tsxToString.tsx
Normal file
16
src/frontend/converter/tsxToString.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react';
|
||||
import { renderToString } from 'react-dom/server';
|
||||
import { StaticRouter } from 'react-router-dom/server';
|
||||
import App from '../components/App';
|
||||
|
||||
const url = process.argv[2];
|
||||
|
||||
const render = () => {
|
||||
return renderToString(
|
||||
<StaticRouter location={`${url}`} >
|
||||
<App />
|
||||
</StaticRouter>
|
||||
);
|
||||
};
|
||||
|
||||
console.log(render());
|
81
src/frontend/index.tsx
Normal file
81
src/frontend/index.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import React from 'react';
|
||||
import { hydrateRoot, createRoot } from 'react-dom/client';
|
||||
// Router
|
||||
import { BrowserRouter as Router } from 'react-router-dom';
|
||||
// Redux
|
||||
import { Provider } from 'react-redux';
|
||||
import { IInitialState } from './reducers/index';
|
||||
import setStore from './setStore';
|
||||
import { config } from '../../config';
|
||||
|
||||
import './styles/global.scss';
|
||||
import App from './components/App';
|
||||
// import serviceWorkerRegistration from '../../serviceWorkerRegistration';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__PRELOADED_STATE__?: IInitialState;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface NodeModule {
|
||||
hot?: IHot;
|
||||
}
|
||||
}
|
||||
|
||||
interface IHot {
|
||||
accept: unknown
|
||||
}
|
||||
|
||||
const { ENV, PREFIX_URL } = config;
|
||||
|
||||
const preloadedState = window.__PRELOADED_STATE__;
|
||||
const store = setStore({ initialState: preloadedState });
|
||||
|
||||
delete window.__PRELOADED_STATE__;
|
||||
|
||||
const container = document.getElementById('app')!;
|
||||
|
||||
if(ENV === 'development') {
|
||||
const root = createRoot(container);
|
||||
root.render(
|
||||
<Provider store={store}>
|
||||
<Router basename={PREFIX_URL}>
|
||||
<App />
|
||||
</Router>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
// add "const root" to be able to rerender.
|
||||
ENV === 'production' && hydrateRoot(container,
|
||||
<Provider store={store}>
|
||||
<Router basename={PREFIX_URL}>
|
||||
<App />
|
||||
</Router>
|
||||
</Provider>,
|
||||
// Add this comment to update later app and remove warning
|
||||
/* {
|
||||
onRecoverableError: (error) => {
|
||||
console.error("recoverable", error);
|
||||
}
|
||||
}, */
|
||||
);
|
||||
|
||||
// Use root.render to update later the app
|
||||
/* root.render(
|
||||
<Provider store={store}>
|
||||
<Router>
|
||||
<App />
|
||||
</Router>
|
||||
</Provider>
|
||||
); */
|
||||
|
||||
/* if((ENV) && (ENV === 'production')){
|
||||
serviceWorkerRegistration();
|
||||
} */
|
||||
|
||||
/* if(module.hot){
|
||||
module.hot.accept();
|
||||
} */
|
14
src/frontend/reducers/index.ts
Normal file
14
src/frontend/reducers/index.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import testReducer from './testReducer';
|
||||
import { IChangeHelloPayload } from '../actions/testAction';
|
||||
|
||||
export interface IInitialState {
|
||||
testReducer?: IChangeHelloPayload | undefined
|
||||
}
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
// Here comes the reducers
|
||||
testReducer
|
||||
});
|
||||
|
||||
export default rootReducer;
|
2
src/frontend/reducers/initialState.ts
Normal file
2
src/frontend/reducers/initialState.ts
Normal file
@ -0,0 +1,2 @@
|
||||
const initialState = {};
|
||||
export default initialState;
|
20
src/frontend/reducers/testReducer.ts
Normal file
20
src/frontend/reducers/testReducer.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { TAction } from '../actions';
|
||||
|
||||
const initialState = {
|
||||
hello: 'world'
|
||||
};
|
||||
|
||||
const testReducer = (state = initialState, action: TAction) => {
|
||||
switch (action.type){
|
||||
case 'CHANGE_HELLO': {
|
||||
const newHello = action.payload.hello;
|
||||
return {
|
||||
hello: newHello
|
||||
};
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default testReducer;
|
27
src/frontend/setStore.ts
Normal file
27
src/frontend/setStore.ts
Normal file
@ -0,0 +1,27 @@
|
||||
// Redux
|
||||
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 reducer, { IInitialState } from './reducers';
|
||||
|
||||
|
||||
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(
|
||||
reducer,
|
||||
initialState,
|
||||
composeEnhancers(),
|
||||
) : createStore(
|
||||
reducer,
|
||||
initialState,
|
||||
);
|
||||
return store;
|
||||
};
|
||||
|
||||
export default setStore;
|
5
src/frontend/styles/global.scss
Normal file
5
src/frontend/styles/global.scss
Normal file
@ -0,0 +1,5 @@
|
||||
$base-color: #282c34;
|
||||
|
||||
body {
|
||||
background-color: $base-color;
|
||||
}
|
15
src/routes/index.tsx
Normal file
15
src/routes/index.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import InitialComponent from '../frontend/components/InitialComponent';
|
||||
import OtherComponent from '../frontend/components/OtherComponent';
|
||||
|
||||
const OTHER_COMPONENT = {
|
||||
path: '/other-component',
|
||||
element: <OtherComponent />
|
||||
};
|
||||
|
||||
const INITIAL_COMPONENT = {
|
||||
path: '/',
|
||||
element: <InitialComponent />,
|
||||
};
|
||||
|
||||
export default [ INITIAL_COMPONENT, OTHER_COMPONENT ];
|
13
src/server/config/config.go
Normal file
13
src/server/config/config.go
Normal file
@ -0,0 +1,13 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func LoadEnv() {
|
||||
err := godotenv.Load(".env")
|
||||
if err != nil {
|
||||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
}
|
49
src/server/go.mod
Normal file
49
src/server/go.mod
Normal file
@ -0,0 +1,49 @@
|
||||
module aleleba/react-server
|
||||
|
||||
go 1.21.1
|
||||
|
||||
require github.com/joho/godotenv v1.5.1
|
||||
|
||||
require github.com/gofiber/fiber/v2 v2.49.1
|
||||
|
||||
require (
|
||||
cloudeng.io/os v0.0.0-20230309184059-9263072b1423 // indirect
|
||||
cloudeng.io/webapp v0.0.0-20230913164637-56a6ca867a22 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/clarkmcc/go-typescript v0.7.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.7.0 // indirect
|
||||
github.com/dop251/goja v0.0.0-20230919151941-fc55792775de // indirect
|
||||
github.com/fasthttp/websocket v1.5.3 // indirect
|
||||
github.com/fatih/color v1.9.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
github.com/githubnemo/CompileDaemon v1.4.0 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
|
||||
github.com/gofiber/adaptor/v2 v2.2.1 // indirect
|
||||
github.com/gofiber/template v1.8.2 // indirect
|
||||
github.com/gofiber/template/html/v2 v2.0.5 // indirect
|
||||
github.com/gofiber/utils v1.1.0 // indirect
|
||||
github.com/gofiber/websocket/v2 v2.2.1 // indirect
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
|
||||
github.com/google/uuid v1.3.1 // indirect
|
||||
github.com/gopherjs/gopherjs v1.17.2 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/klauspost/compress v1.16.7 // indirect
|
||||
github.com/labstack/echo/v4 v4.11.1 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/radovskyb/watcher v1.0.7 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/robertkrimen/otto v0.2.1 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.49.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
golang.org/x/crypto v0.11.0 // indirect
|
||||
golang.org/x/net v0.12.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.11.0 // indirect
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
)
|
212
src/server/go.sum
Normal file
212
src/server/go.sum
Normal file
@ -0,0 +1,212 @@
|
||||
cloudeng.io/algo v0.0.0-20221118174443-5eef698118a6/go.mod h1:dgJhQ6JXLysnBQG09/5Q56rwJfgyKXlnDbKzko9MhdA=
|
||||
cloudeng.io/algo v0.0.0-20230304024356-5d6b315e83f0/go.mod h1:80eC8gNGsJP8ZBw+xCIh1kIpt77az1W7fJ+zqLRiE64=
|
||||
cloudeng.io/algo v0.0.0-20230307023515-8a194fbc7867/go.mod h1:80eC8gNGsJP8ZBw+xCIh1kIpt77az1W7fJ+zqLRiE64=
|
||||
cloudeng.io/cmdutil v0.0.0-20230130231933-fe585c604aed/go.mod h1:nX3v2San8WLgYYmtom/+1GxmfKh3wWSyvnLvoxUz784=
|
||||
cloudeng.io/cmdutil v0.0.0-20230309184059-9263072b1423/go.mod h1:HOYjjVIvIbRF5li5EIzqyFYxlzPmxNskXO74HDICgk8=
|
||||
cloudeng.io/debug v0.0.0-20230105021008-948d22470af5/go.mod h1:UDKUtuaCh0+iaDe5+i70G3l3liexOPeU3h0lyUeAt+o=
|
||||
cloudeng.io/errors v0.0.7/go.mod h1:xWamLL6tn3roKI6MRRFkw1jUkJL9s7CJzFYfaxuhHZk=
|
||||
cloudeng.io/errors v0.0.8/go.mod h1:xWamLL6tn3roKI6MRRFkw1jUkJL9s7CJzFYfaxuhHZk=
|
||||
cloudeng.io/file v0.0.0-20230221162436-db7c7fd2cf04/go.mod h1:kcAJeuW9/AL/sw/sySiIoF+BHjDKcHawqTPyDAdwmrQ=
|
||||
cloudeng.io/file v0.0.0-20230306215119-e71b407605cc/go.mod h1:1wtCIz069qanFkcbpb8F3msDf+W7G3Wjw5Om+KISyuQ=
|
||||
cloudeng.io/file v0.0.0-20230309184059-9263072b1423/go.mod h1:Ow6f4Wu+6U8XQFP4U2Kr9izv+oU/jVMZyuCTmf6FaOc=
|
||||
cloudeng.io/io v0.0.0-20230309184059-9263072b1423/go.mod h1:6Scpv2/l9yI5tTE0esMr5SN1bemcRhm4d+RR6tCeH1M=
|
||||
cloudeng.io/net v0.0.0-20230214072348-e50d5014b274/go.mod h1:13BN0nf3e35fdeiFH0pgduqEhOgWLMvnhYtRYg4WKE8=
|
||||
cloudeng.io/net v0.0.0-20230304024356-5d6b315e83f0/go.mod h1:D0bZpZHSBIlyvBG/i+JOubQDjxbYJX/eas8v9byykfc=
|
||||
cloudeng.io/net v0.0.0-20230307023515-8a194fbc7867/go.mod h1:b7cZgzjeLZxVX1DJAEEQSdI9zLhruVy9XG20voObvKk=
|
||||
cloudeng.io/os v0.0.0-20221118174443-5eef698118a6/go.mod h1:hhGubbGRTXGbe6T0ZU2RSXfCo1Ktvzfb0BcpkK4xqvY=
|
||||
cloudeng.io/os v0.0.0-20230304024356-5d6b315e83f0/go.mod h1:Ak4HQwvBx5/6w5XT9VKS1BekYSi6QQAEvlbOtzN7eJA=
|
||||
cloudeng.io/os v0.0.0-20230307023515-8a194fbc7867/go.mod h1:gBS7WALqIPNN8ovv1DIuf5/MlQ90mKDjMSjwN/ZvoD4=
|
||||
cloudeng.io/os v0.0.0-20230309184059-9263072b1423 h1:+COcYDTwuT4AhsSq2G/BreMJgky2J9atZpVfGnh+Now=
|
||||
cloudeng.io/os v0.0.0-20230309184059-9263072b1423/go.mod h1:6qBe7uAG6enJ7Nt+4Z8ddua57LYK4pnlmaDMGJxa/3s=
|
||||
cloudeng.io/path v0.0.4/go.mod h1:HTU24UoiQVjzSjN+K2kD8hpkBnoLGZh0OITJr3kfxUk=
|
||||
cloudeng.io/path v0.0.8/go.mod h1:S9dU9pNDkx0EUIHY+Pcyfzs3/cItCI9lyClkwqv0PtM=
|
||||
cloudeng.io/sync v0.0.8/go.mod h1:76qdZzMQSN+iPeQxY9MSbnSELKQmcd9E6pnfRgWgN8s=
|
||||
cloudeng.io/sys v0.0.0-20211030052257-ec4c6f8b878e/go.mod h1:fNIWqX26NzdShrH3lBfxzPhP1jju7JOt7Rg8PxBvYvA=
|
||||
cloudeng.io/sys v0.0.0-20221118174443-5eef698118a6/go.mod h1:fNIWqX26NzdShrH3lBfxzPhP1jju7JOt7Rg8PxBvYvA=
|
||||
cloudeng.io/sys v0.0.0-20230221162436-db7c7fd2cf04/go.mod h1:DPEAeWYUvJ684GySwz0pzPtYxaPnZ7dyz1NHUcdNCEk=
|
||||
cloudeng.io/sys v0.0.0-20230304024356-5d6b315e83f0/go.mod h1:R5nydEKnw8t2BjpQH87CGG59WEBb2rcRRTsqz1Ak5/s=
|
||||
cloudeng.io/sys v0.0.0-20230306215119-e71b407605cc/go.mod h1:Lt8onmpJi8I5Xt2EyHtIfPkn4YaH12n4ehTr199ZGjY=
|
||||
cloudeng.io/sys v0.0.0-20230307023515-8a194fbc7867/go.mod h1:Lt8onmpJi8I5Xt2EyHtIfPkn4YaH12n4ehTr199ZGjY=
|
||||
cloudeng.io/text v0.0.11/go.mod h1:99L3CQ55YhUy2+lHlFPowYyCoXO86fmkvNtcMT2X3GU=
|
||||
cloudeng.io/webapp v0.0.0-20230913164637-56a6ca867a22 h1:q1HmQki39a8BC9qPu62b3OnGsk0kohKzZseATT/8PpU=
|
||||
cloudeng.io/webapp v0.0.0-20230913164637-56a6ca867a22/go.mod h1:udLHBvexojKGB0JgZjJW3ZzDaSCqNU566KTbpK9EFmM=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
|
||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||
github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clarkmcc/go-typescript v0.7.0 h1:3nVeaPYyTCWjX6Lf8GoEOTxME2bM5tLuWmwhSZ86uxg=
|
||||
github.com/clarkmcc/go-typescript v0.7.0/go.mod h1:IZ/nzoVeydAmyfX7l6Jmp8lJDOEnae3jffoXwP4UyYg=
|
||||
github.com/cosnicolaou/pudge v1.0.6/go.mod h1:PSbC4eylkssiQ+gAE+AWaMQSo41g/otqflfbcsMrupk=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
|
||||
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
|
||||
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||
github.com/dop251/goja v0.0.0-20211115154819-26ebff68a7d5 h1:7eyn0Cp9ezNbo2Vb4ttgJyWsFrRWP3oyHEw4PHKYlps=
|
||||
github.com/dop251/goja v0.0.0-20211115154819-26ebff68a7d5/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
|
||||
github.com/dop251/goja v0.0.0-20230919151941-fc55792775de h1:lA38Xtzr1Wo+iQdkN2E11ziKXJYRxLlzK/e2/fdxoEI=
|
||||
github.com/dop251/goja v0.0.0-20230919151941-fc55792775de/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
|
||||
github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM=
|
||||
github.com/fasthttp/websocket v1.5.3 h1:TPpQuLwJYfd4LJPXvHDYPMFWbLjsT91n3GpWtCQtdek=
|
||||
github.com/fasthttp/websocket v1.5.3/go.mod h1:46gg/UBmTU1kUaTcwQXpUxtRwG2PvIZYeA8oL6vF3Fs=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/githubnemo/CompileDaemon v1.4.0 h1:z96Qu4tj+RzRfF+L7f1O6E8ion5JQlisWeXWc2wzwDQ=
|
||||
github.com/githubnemo/CompileDaemon v1.4.0/go.mod h1:/G125r3YBIp6rcXtCZfiEHwFzcl7GSsNSwylxSNrkMA=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
|
||||
github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/gofiber/adaptor/v2 v2.2.1 h1:givE7iViQWlsTR4Jh7tB4iXzrlKBgiraB/yTdHs9Lv4=
|
||||
github.com/gofiber/adaptor/v2 v2.2.1/go.mod h1:AhR16dEqs25W2FY/l8gSj1b51Azg5dtPDmm+pruNOrc=
|
||||
github.com/gofiber/fiber/v2 v2.49.1 h1:0W2DRWevSirc8pJl4o8r8QejDR8TV6ZUCawHxwbIdOk=
|
||||
github.com/gofiber/fiber/v2 v2.49.1/go.mod h1:nPUeEBUeeYGgwbDm59Gp7vS8MDyScL6ezr/Np9A13WU=
|
||||
github.com/gofiber/template v1.8.2 h1:PIv9s/7Uq6m+Fm2MDNd20pAFFKt5wWs7ZBd8iV9pWwk=
|
||||
github.com/gofiber/template v1.8.2/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
|
||||
github.com/gofiber/template/html/v2 v2.0.5 h1:BKLJ6Qr940NjntbGmpO3zVa4nFNGDCi/IfUiDB9OC20=
|
||||
github.com/gofiber/template/html/v2 v2.0.5/go.mod h1:RCF14eLeQDCSUPp0IGc2wbSSDv6yt+V54XB/+Unz+LM=
|
||||
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
|
||||
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
|
||||
github.com/gofiber/websocket/v2 v2.2.1 h1:C9cjxvloojayOp9AovmpQrk8VqvVnT8Oao3+IUygH7w=
|
||||
github.com/gofiber/websocket/v2 v2.2.1/go.mod h1:Ao/+nyNnX5u/hIFPuHl28a+NIkrqK7PRimyKaj4JxVU=
|
||||
github.com/google/pprof v0.0.0-20221219190121-3cb0bae90811/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U=
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
|
||||
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.11.1 h1:dEpLU2FLg4UVmvCGPuk/APjlH6GDpbEPti61srUUUs4=
|
||||
github.com/labstack/echo/v4 v4.11.1/go.mod h1:YuYRTSM3CHs2ybfrL8Px48bO6BAnYIN4l8wSTMP6BDQ=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/radovskyb/watcher v1.0.7 h1:AYePLih6dpmS32vlHfhCeli8127LzkIgwJGcwwe8tUE=
|
||||
github.com/radovskyb/watcher v1.0.7/go.mod h1:78okwvY5wPdzcb1UYnip1pvrZNIVEIh/Cm+ZuvsUYIg=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/robertkrimen/otto v0.2.1 h1:FVP0PJ0AHIjC+N4pKCG9yCDz6LHNPCwi/GKID5pGGF0=
|
||||
github.com/robertkrimen/otto v0.2.1/go.mod h1:UPwtJ1Xu7JrLcZjNWN8orJaM5n5YEtqL//farB5FlRY=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
|
||||
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.49.0 h1:9FdvCpmxB74LH4dPb7IJ1cOSsluR07XG3I1txXWwJpE=
|
||||
github.com/valyala/fasthttp v1.49.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
|
||||
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
|
||||
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
|
||||
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
|
||||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
106
src/server/main.go
Normal file
106
src/server/main.go
Normal file
@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"aleleba/react-server/config"
|
||||
"aleleba/react-server/web"
|
||||
"aleleba/react-server/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config.LoadEnv()
|
||||
}
|
||||
|
||||
func main() {
|
||||
//Getting the port from the environment
|
||||
port := os.Getenv("PORT")
|
||||
|
||||
paths := utils.GetRoutes()
|
||||
|
||||
e := echo.New()
|
||||
|
||||
// Watch for file changes in the ./web/dist directory
|
||||
watcher, err := fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer watcher.Close()
|
||||
|
||||
if err := filepath.Walk("./web", func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.IsDir() {
|
||||
if err := watcher.Add(path); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Create a websocket upgrader
|
||||
upgrader := websocket.Upgrader{}
|
||||
|
||||
// Handle websocket connections
|
||||
e.GET("/ws", func(c echo.Context) error {
|
||||
// Upgrade the HTTP connection to a websocket connection
|
||||
ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Watch for file changes in the ./web/dist directory
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-watcher.Events:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
fmt.Println("modified file:", event.Name)
|
||||
|
||||
// Send a message to the client to reload the page
|
||||
if err := ws.WriteMessage(websocket.TextMessage, []byte("reload")); err != nil {
|
||||
fmt.Println("error sending message:", err)
|
||||
}
|
||||
}
|
||||
case err, ok := <-watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
fmt.Println("error:", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Read messages from the client (not used in this example)
|
||||
/*for {
|
||||
_, _, err := ws.ReadMessage()
|
||||
if err != nil {
|
||||
fmt.Println("error reading message:", err)
|
||||
break
|
||||
}
|
||||
}*/
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
web.RegisterHandlers(e, paths)
|
||||
|
||||
// Add your custom api routes here.
|
||||
// Example:
|
||||
e.GET("/api", func(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "Hello, World!")
|
||||
})
|
||||
|
||||
e.Logger.Fatal(e.Start(":" + port))
|
||||
}
|
37
src/server/utils/jsxToStringExecuter.go
Normal file
37
src/server/utils/jsxToStringExecuter.go
Normal file
@ -0,0 +1,37 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func JsxToString(url string) string {
|
||||
// Set the path to the jsxToString.js file
|
||||
jsFilePath := "./web/utils/tsxToString.js"
|
||||
|
||||
// Create the command to run Node.js with the jsxToString.js file
|
||||
cmd := exec.Command("node", jsFilePath, url)
|
||||
|
||||
// Get a pipe to the standard input of the Node.js process
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
// Write the URL parameter to the standard input of the Node.js process
|
||||
fmt.Fprintf(stdin, "%s\n", url)
|
||||
|
||||
// Close the standard input pipe
|
||||
stdin.Close()
|
||||
|
||||
// Get the output and error of the Node.js process
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return string(output)
|
||||
}
|
||||
|
||||
// Return the output of the Node.js process
|
||||
return string(output)
|
||||
}
|
31
src/server/utils/readRoutes.go
Normal file
31
src/server/utils/readRoutes.go
Normal file
@ -0,0 +1,31 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"regexp"
|
||||
"github.com/clarkmcc/go-typescript"
|
||||
)
|
||||
|
||||
func GetRoutes () []string {
|
||||
// Read the contents of the TypeScript file
|
||||
content, err := os.ReadFile("../routes/index.tsx")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Transpile the TypeScript code to JavaScript
|
||||
jsCode, err := typescript.TranspileString(string(content))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Extract the "path" values from the transpiled JavaScript code
|
||||
re := regexp.MustCompile(`path:\s*['"]([^'"]+)['"]`)
|
||||
matches := re.FindAllStringSubmatch(jsCode, -1)
|
||||
paths := make([]string, 0)
|
||||
for _, match := range matches {
|
||||
paths = append(paths, match[1])
|
||||
}
|
||||
|
||||
return paths
|
||||
}
|
61
src/server/web/web.go
Normal file
61
src/server/web/web.go
Normal file
@ -0,0 +1,61 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"embed"
|
||||
//"path/filepath"
|
||||
//"fmt"
|
||||
"net/http"
|
||||
"github.com/labstack/echo/v4"
|
||||
"aleleba/react-server/utils"
|
||||
)
|
||||
|
||||
// embed the dist folder
|
||||
var (
|
||||
//go:embed dist/*
|
||||
dist embed.FS
|
||||
|
||||
indexHTML embed.FS
|
||||
distDirFS = echo.MustSubFS(dist, "dist")
|
||||
//distIndexHtml = echo.MustSubFS(indexHTML, "dist")
|
||||
)
|
||||
|
||||
func RegisterHandlers(e *echo.Echo, paths []string) {
|
||||
// Print the "path" values
|
||||
for _, path := range paths {
|
||||
//e.FileFS(path, "index.html", distIndexHtml)
|
||||
//e.StaticFS(path, distDirFS)
|
||||
e.Static(path, "web/dist")
|
||||
e.GET(path, func(c echo.Context) error {
|
||||
// Construct the file path
|
||||
//filePath := filepath.Join("web", "dist", "index.html")
|
||||
// Return the HTML file
|
||||
//return c.File(filePath)
|
||||
url := c.Request().URL.String()
|
||||
component := utils.JsxToString(url)
|
||||
html := `<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!-- ${manifestJson} -->
|
||||
<link href="assets/frontend.css" rel="stylesheet" type="text/css"></link>
|
||||
|
||||
<title>App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">`+ component +`</div>
|
||||
<!-- <script>
|
||||
window.__PRELOADED_STATE__ = ${JSON.stringify(preloadedState).replace(/</g, '\\u003c')}
|
||||
</script> -->
|
||||
<script src="assets/app-frontend.js" type="text/javascript"></script>
|
||||
<script src="assets/vendor-vendors.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>`
|
||||
return c.HTMLBlob(http.StatusOK, []byte(html))
|
||||
})
|
||||
}
|
||||
|
||||
}
|
57
tsconfig.json
Normal file
57
tsconfig.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"noEmit": false,
|
||||
"jsx": "react-jsx",
|
||||
"experimentalDecorators": true,
|
||||
"esModuleInterop": true,
|
||||
"isolatedModules": false,
|
||||
"typeRoots" : ["./src/@types", "./node_modules/@types"],
|
||||
"types": [
|
||||
"react",
|
||||
"react-dom",
|
||||
"node"
|
||||
],
|
||||
"sourceMap": false,
|
||||
"baseUrl": ".",
|
||||
"outDir": "build",
|
||||
"skipLibCheck": true,
|
||||
"noImplicitAny": false,
|
||||
"paths": {
|
||||
"@components/*": ["src/frontend/components/*"],
|
||||
"@components": ["src/frontend/components"],
|
||||
"@styles/*": ["src/frontend/styles/*"],
|
||||
"@styles": ["src/frontend/styles"],
|
||||
"@actions/*": ["src/frontend/actions/*"],
|
||||
"@actions": ["src/frontend/actions"],
|
||||
"@reducers/*": ["src/frontend/reducers"],
|
||||
"@reducers": ["src/frontend/reducers"],
|
||||
"@config/*": ["config/*"],
|
||||
"@config": ["config"],
|
||||
"@mocks/*": ["src/__mocks__/*"],
|
||||
"@mocks": ["src/__mocks__"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"."
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"build",
|
||||
"PRNameGenerator.ts",
|
||||
"cypress.config.ts"
|
||||
]
|
||||
}
|
216
webpack.config.ts
Normal file
216
webpack.config.ts
Normal file
@ -0,0 +1,216 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { config as envConfig } from './config';
|
||||
import webpack from 'webpack';
|
||||
import CompressionWebpackPlugin from 'compression-webpack-plugin';
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
||||
import TerserPlugin from 'terser-webpack-plugin';
|
||||
import { WebpackManifestPlugin } from 'webpack-manifest-plugin';
|
||||
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
||||
import ESLintPlugin from 'eslint-webpack-plugin';
|
||||
import CopyPlugin from 'copy-webpack-plugin';
|
||||
import { resolveTsAliases } from 'resolve-ts-aliases';
|
||||
|
||||
const ROOT_DIR = path.resolve(__dirname);
|
||||
const resolvePath = (...args) => path.resolve(ROOT_DIR, ...args);
|
||||
const BUILD_DIR = resolvePath(__dirname + '/src/server/web/dist');
|
||||
const BUILD_DIR_CONVERSION = resolvePath(__dirname + '/src/server/web/utils');
|
||||
//const { InjectManifest } = require('workbox-webpack-plugin');
|
||||
//const nodeExternals = require('webpack-node-externals');
|
||||
const alias = resolveTsAliases(path.resolve('tsconfig.json'));
|
||||
|
||||
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 configReact = {
|
||||
entry: {
|
||||
frontend: `${ROOT_DIR}/src/frontend/index.tsx`,
|
||||
},
|
||||
output: {
|
||||
path: BUILD_DIR,
|
||||
//filename: 'assets/app-[name]-[fullhash].js',
|
||||
filename: 'assets/app-[name].js',
|
||||
publicPath: envConfig.PUBLIC_URL,
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
|
||||
alias,
|
||||
},
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(css|sass|scss)$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
'sass-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|jpeg|gif|svg|ico|mp4|avi|ttf|otf|eot|woff|woff2|pdf)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'assets/[name].[ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|otf|eot|woff|woff2)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: 'assets/fonts/[name].[ext]',
|
||||
esModule: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CompressionWebpackPlugin({
|
||||
test: /\.(js|css)$/,
|
||||
filename: '[path][base].gz',
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
//filename: 'assets/[name]-[fullhash].css',
|
||||
filename: 'assets/[name].css',
|
||||
}),
|
||||
new WebpackManifestPlugin({
|
||||
fileName: 'assets/manifest-hash.json',
|
||||
publicPath: envConfig.PREFIX_URL,
|
||||
}),
|
||||
new CleanWebpackPlugin({
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'**/*',
|
||||
'!server/**',
|
||||
],
|
||||
}),
|
||||
new ESLintPlugin(),
|
||||
new webpack.EnvironmentPlugin({
|
||||
...envConfig,
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: copyPatterns
|
||||
}),
|
||||
/*new InjectManifest({
|
||||
swSrc: './service-worker.ts',
|
||||
swDest: 'service-worker.js',
|
||||
}),*/
|
||||
],
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new CssMinimizerPlugin(),
|
||||
new TerserPlugin(),
|
||||
],
|
||||
splitChunks: {
|
||||
chunks: 'async',
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
name: 'vendors',
|
||||
chunks: 'all',
|
||||
reuseExistingChunk: true,
|
||||
priority: 1,
|
||||
//filename: 'assets/vendor-[name]-[fullhash].js',
|
||||
filename: 'assets/vendor-[name].js',
|
||||
enforce: true,
|
||||
test (module, chunks){
|
||||
const name = module.nameForCondition && module.nameForCondition();
|
||||
return chunks.name !== 'vendors' && /[\\/]node_modules[\\/]/.test(name);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const configTSXConversion = {
|
||||
entry: {
|
||||
tsxToString: `${ROOT_DIR}/src/frontend/converter/tsxToString.tsx`,
|
||||
},
|
||||
output: {
|
||||
path: BUILD_DIR_CONVERSION,
|
||||
//filename: 'assets/app-[name]-[fullhash].js',
|
||||
filename: '[name].js',
|
||||
publicPath: envConfig.PUBLIC_URL,
|
||||
globalObject: 'this',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
|
||||
alias,
|
||||
},
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(css|sass|scss)$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
'sass-loader',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CompressionWebpackPlugin({
|
||||
test: /\.(js|css)$/,
|
||||
filename: '[path][base].gz',
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
//filename: 'assets/[name]-[fullhash].css',
|
||||
filename: '[name].css',
|
||||
}),
|
||||
new CleanWebpackPlugin({
|
||||
cleanOnceBeforeBuildPatterns: [
|
||||
'**/*',
|
||||
'!server/**',
|
||||
],
|
||||
}),
|
||||
new ESLintPlugin(),
|
||||
new webpack.EnvironmentPlugin({
|
||||
...envConfig,
|
||||
}),
|
||||
],
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new CssMinimizerPlugin(),
|
||||
new TerserPlugin(),
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export default [configReact, configTSXConversion];
|
97
webpack.cy.config.ts
Normal file
97
webpack.cy.config.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import { config as envConfig } from './config';
|
||||
import webpack from 'webpack';
|
||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
|
||||
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
||||
import TerserPlugin from 'terser-webpack-plugin';
|
||||
import ESLintPlugin from 'eslint-webpack-plugin';
|
||||
import CopyPlugin from 'copy-webpack-plugin';
|
||||
import { resolveTsAliases } from 'resolve-ts-aliases';
|
||||
|
||||
const alias = resolveTsAliases(path.resolve('tsconfig.json'));
|
||||
const copyPatterns: {from: string, to: string}[] = [];
|
||||
|
||||
const copyFromUrl = `${path.resolve(__dirname)}/public/img`;
|
||||
const copyToUrl = 'assets/img';
|
||||
|
||||
if(fs.existsSync(copyFromUrl)){
|
||||
copyPatterns.push({
|
||||
from: copyFromUrl, to: copyToUrl,
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
entry: './src/frontend/components/index.tsx',
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx','.ts','.tsx', '.json'],
|
||||
alias,
|
||||
},
|
||||
mode: 'development',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'build'),
|
||||
},
|
||||
target: 'web',
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'index.css',
|
||||
}),
|
||||
new ESLintPlugin(),
|
||||
new webpack.EnvironmentPlugin({
|
||||
...envConfig,
|
||||
}),
|
||||
new CopyPlugin({
|
||||
patterns: copyPatterns
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: path.join(__dirname, 'build', 'index.html'),
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
React: 'react',
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|ts|tsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(css|sass|scss)$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
'sass-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|jpeg|gif|svg|ico|mp4|avi|ttf|otf|eot|woff|woff2|pdf)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: 'assets/[name].[ext]',
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(ttf|otf|eot|woff|woff2)$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: 'assets/fonts/[name].[ext]',
|
||||
esModule: false,
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [
|
||||
new CssMinimizerPlugin(),
|
||||
new TerserPlugin(),
|
||||
],
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue
Block a user