updates to frontend-react
This commit is contained in:
24
Web/WebSocket/websocket/apps/frontend-react/.gitignore
vendored
Normal file
24
Web/WebSocket/websocket/apps/frontend-react/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
2
Web/WebSocket/websocket/apps/frontend-react/.npmrc
Normal file
2
Web/WebSocket/websocket/apps/frontend-react/.npmrc
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
save-exact=true
|
||||||
|
package-lock=false
|
||||||
1
Web/WebSocket/websocket/apps/frontend-react/.nvmrc
Normal file
1
Web/WebSocket/websocket/apps/frontend-react/.nvmrc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
24
|
||||||
12
Web/WebSocket/websocket/apps/frontend-react/.prettierrc
Normal file
12
Web/WebSocket/websocket/apps/frontend-react/.prettierrc
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"bracketSameLine": true,
|
||||||
|
"bracketSpacing": false,
|
||||||
|
"printWidth": 160,
|
||||||
|
"semi": true,
|
||||||
|
"singleAttributePerLine": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"useTabs": false
|
||||||
|
}
|
||||||
73
Web/WebSocket/websocket/apps/frontend-react/README.md
Normal file
73
Web/WebSocket/websocket/apps/frontend-react/README.md
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# React + TypeScript + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
|
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||||
|
|
||||||
|
## React Compiler
|
||||||
|
|
||||||
|
The React Compiler is currently not compatible with SWC. See [this issue](https://github.com/vitejs/vite-plugin-react/issues/428) for tracking the progress.
|
||||||
|
|
||||||
|
## Expanding the ESLint configuration
|
||||||
|
|
||||||
|
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
// Other configs...
|
||||||
|
|
||||||
|
// Remove tseslint.configs.recommended and replace with this
|
||||||
|
tseslint.configs.recommendedTypeChecked,
|
||||||
|
// Alternatively, use this for stricter rules
|
||||||
|
tseslint.configs.strictTypeChecked,
|
||||||
|
// Optionally, add this for stylistic rules
|
||||||
|
tseslint.configs.stylisticTypeChecked
|
||||||
|
|
||||||
|
// Other configs...
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname
|
||||||
|
}
|
||||||
|
// other options...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// eslint.config.js
|
||||||
|
import reactX from 'eslint-plugin-react-x';
|
||||||
|
import reactDom from 'eslint-plugin-react-dom';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [
|
||||||
|
// Other configs...
|
||||||
|
// Enable lint rules for React
|
||||||
|
reactX.configs['recommended-typescript'],
|
||||||
|
// Enable lint rules for React DOM
|
||||||
|
reactDom.configs.recommended
|
||||||
|
],
|
||||||
|
languageOptions: {
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname
|
||||||
|
}
|
||||||
|
// other options...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
```
|
||||||
18
Web/WebSocket/websocket/apps/frontend-react/eslint.config.js
Normal file
18
Web/WebSocket/websocket/apps/frontend-react/eslint.config.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import js from '@eslint/js';
|
||||||
|
import globals from 'globals';
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks';
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh';
|
||||||
|
import tseslint from 'typescript-eslint';
|
||||||
|
import {defineConfig, globalIgnores} from 'eslint/config';
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
globalIgnores(['dist']),
|
||||||
|
{
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
extends: [js.configs.recommended, tseslint.configs.recommended, reactHooks.configs['recommended-latest'], reactRefresh.configs.vite],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
globals: globals.browser
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
13
Web/WebSocket/websocket/apps/frontend-react/index.html
Normal file
13
Web/WebSocket/websocket/apps/frontend-react/index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>frontend-react</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
36
Web/WebSocket/websocket/apps/frontend-react/package.json
Normal file
36
Web/WebSocket/websocket/apps/frontend-react/package.json
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend-react",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc -b && vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "2.9.0",
|
||||||
|
"react": "^19.1.1",
|
||||||
|
"react-dom": "^19.1.1",
|
||||||
|
"react-redux": "9.2.0",
|
||||||
|
"styled-components": "6.1.19"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.36.0",
|
||||||
|
"@techniker-me/websocket-shared-types": "*",
|
||||||
|
"@types/react": "^19.1.13",
|
||||||
|
"@types/react-dom": "^19.1.9",
|
||||||
|
"@vitejs/plugin-react-swc": "^4.1.0",
|
||||||
|
"babel-plugin-styled-components": "2.1.4",
|
||||||
|
"babel-plugin-transform-amd-to-commonjs": "1.6.0",
|
||||||
|
"eslint": "^9.36.0",
|
||||||
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.20",
|
||||||
|
"globals": "^16.4.0",
|
||||||
|
"typescript": "~5.8.3",
|
||||||
|
"typescript-eslint": "^8.44.0",
|
||||||
|
"vite": "^7.1.7",
|
||||||
|
"vite-plugin-babel": "1.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Web/WebSocket/websocket/apps/frontend-react/src/App.tsx
Normal file
10
Web/WebSocket/websocket/apps/frontend-react/src/App.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import {LoginView} from './views';
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
console.log('APP')
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<LoginView />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface ILoginFormProps {
|
||||||
|
onSubmit: (username: string, secret: string) => void;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import ILoginFormPops from './ILoginFormProps';
|
||||||
|
import { Input } from './Styled';
|
||||||
|
|
||||||
|
export function LoginForm({ onSubmit }: ILoginFormProps) {
|
||||||
|
const [username, setUsername] = useState<string>('');
|
||||||
|
const [secret, setSecret] = useState<string>('');
|
||||||
|
|
||||||
|
// The submit handler now correctly uses 'event'
|
||||||
|
const handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
event.preventDefault();
|
||||||
|
onSubmit(username, secret);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleFormSubmit}>
|
||||||
|
{/*
|
||||||
|
- The 'placeholder' prop is now lowercase.
|
||||||
|
- The 'onChange' handler correctly destructures {target}.
|
||||||
|
*/}
|
||||||
|
<Input
|
||||||
|
type="text"
|
||||||
|
placeholder="Username"
|
||||||
|
autoComplete="username"
|
||||||
|
value={username}
|
||||||
|
onChange={({ target }) => setUsername(target.value)}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="password"
|
||||||
|
placeholder="Password"
|
||||||
|
autoComplete="current-password"
|
||||||
|
value={secret}
|
||||||
|
onChange={({ target }) => setSecret(target.value)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button type="submit">Login</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
export const Input = styled.input`
|
||||||
|
width: 100%;
|
||||||
|
heght: 1.3rem;
|
||||||
|
backgroundColor: blue
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Button = styled.button`
|
||||||
|
width: fit-content;
|
||||||
|
margin: auto;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #a7c42;
|
||||||
|
|
||||||
|
`
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from './ILoginFormProps';
|
||||||
|
export * from './LoginForm';
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './LoginForm';
|
||||||
68
Web/WebSocket/websocket/apps/frontend-react/src/index.css
Normal file
68
Web/WebSocket/websocket/apps/frontend-react/src/index.css
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
:root {
|
||||||
|
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
|
||||||
|
color-scheme: light dark;
|
||||||
|
color: rgba(255, 255, 255, 0.87);
|
||||||
|
background-color: #242424;
|
||||||
|
|
||||||
|
font-synthesis: none;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #646cff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #535bf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
border-color: #646cff;
|
||||||
|
}
|
||||||
|
button:focus,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
:root {
|
||||||
|
color: #213547;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #747bff;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Web/WebSocket/websocket/apps/frontend-react/src/main.tsx
Normal file
13
Web/WebSocket/websocket/apps/frontend-react/src/main.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import {StrictMode} from 'react';
|
||||||
|
import {createRoot} from 'react-dom/client';
|
||||||
|
import {Provider} from 'react-redux';
|
||||||
|
import store from './store';
|
||||||
|
import App from './App.tsx';
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<StrictMode>
|
||||||
|
<App />
|
||||||
|
</StrictMode>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import {configureStore} from '@reduxjs/toolkit';
|
||||||
|
import {userSlice} from './slices';
|
||||||
|
|
||||||
|
// Configure the main store
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
// Add the reducer from your slice to the store
|
||||||
|
user: userSlice.reducer
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default store;
|
||||||
|
|
||||||
|
// Type definition for the root state, can be used with useSelector hook
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
|
||||||
|
// Type definition for dispatch, can be used with useDispatch hook
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import {createSlice, configureStore, PayloadAction} from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
interface IUserState {
|
||||||
|
id: string | null;
|
||||||
|
name: string | null;
|
||||||
|
isLoading: boolean;
|
||||||
|
error: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: IUserState = {
|
||||||
|
id: null,
|
||||||
|
name: null,
|
||||||
|
isLoading: false,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
|
||||||
|
export const userSlice = createSlice({
|
||||||
|
name: 'user', // A name for this slice, used in action types
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
// The key here becomes part of the action type: 'user/setUserLoading'
|
||||||
|
setUserLoading(state, action: PayloadAction<boolean>) {
|
||||||
|
// Redux Toolkit uses Immer, so you can "mutate" the state directly.
|
||||||
|
// Immer handles the immutable update behind the scenes.
|
||||||
|
state.isLoading = action.payload;
|
||||||
|
},
|
||||||
|
userFetchSuccess(state, action: PayloadAction<{id: string; name: string}>) {
|
||||||
|
state.isLoading = false;
|
||||||
|
state.id = action.payload.id;
|
||||||
|
state.name = action.payload.name;
|
||||||
|
state.error = null;
|
||||||
|
},
|
||||||
|
userFetchError(state, action: PayloadAction<string>) {
|
||||||
|
state.isLoading = false;
|
||||||
|
state.error = action.payload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {setUserLoading, userFetchSuccess, userFetchError} = userSlice.actions;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './User.slice';
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
import {LoginForm} from '../../components';
|
||||||
|
|
||||||
|
export function LoginView() {
|
||||||
|
const handleLoginSubmit = (username: string, secret: string) => {
|
||||||
|
console.log('handling login submit username [%o] secret [%o]', username, secret)
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('LoginView...')
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<LoginForm onSubmit={handleLoginSubmit} />
|
||||||
|
</>
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './LoginView';
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"target": "ES2022",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"types": ["vite/client"],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [{"path": "./tsconfig.app.json"}, {"path": "./tsconfig.node.json"}]
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "ES2023",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"types": [],
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
95
Web/WebSocket/websocket/apps/frontend-react/vite.config.ts
Normal file
95
Web/WebSocket/websocket/apps/frontend-react/vite.config.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import type {UserConfig} from 'vite';
|
||||||
|
|
||||||
|
import path from 'node:path';
|
||||||
|
import {defineConfig} from 'vite';
|
||||||
|
import VitePluginReact from '@vitejs/plugin-react-swc';
|
||||||
|
import ViteBabelPlugin from 'vite-plugin-babel';
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig(({mode}) => {
|
||||||
|
const isProductionMode = mode === 'production';
|
||||||
|
|
||||||
|
// optional: const modeDependentEnvironmentVariables = loadEnv(mode, process.cwd()); // https://vite.dev/config/#using-environment-variables-in-config
|
||||||
|
return {
|
||||||
|
define: {},
|
||||||
|
root: path.resolve(process.cwd()),
|
||||||
|
publicDir: 'public',
|
||||||
|
cacheDir: 'node_modules/.vite', // default is `node_modules/.vite` <-- https://vite.dev/config/shared-options.html#cachedir
|
||||||
|
base: '/',
|
||||||
|
mode,
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
assets: path.resolve(process.cwd(), 'src/assets'),
|
||||||
|
components: path.resolve(process.cwd(), 'src/components'),
|
||||||
|
services: path.resolve(process.cwd(), 'src/services'),
|
||||||
|
store: path.resolve(process.cwd(), 'src/store'),
|
||||||
|
styles: path.resolve(process.cwd(), 'src/styles'),
|
||||||
|
themes: path.resolve(process.cwd(), 'src/themes'),
|
||||||
|
utils: path.resolve(process.cwd(), 'src/utils'),
|
||||||
|
views: path.resolve(process.cwd(), 'src/views')
|
||||||
|
},
|
||||||
|
dedupe: [],
|
||||||
|
conditions: ['module', 'browser', 'development|production'], // default is `['module', 'browser', 'development|production']`
|
||||||
|
mainFields: ['browser', 'module'], // default is `['browser', 'module', 'jsnext:main', 'jsnext']`
|
||||||
|
extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],
|
||||||
|
preserveSymlinks: false // default is false
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
modules: undefined, // default is `undefined`
|
||||||
|
// postcss: {},
|
||||||
|
devSourcemap: true, // default is `false` **experimental Vite feature**
|
||||||
|
transformer: 'postcss' // default is `postcss` **experimental Vite feature**
|
||||||
|
},
|
||||||
|
json: {
|
||||||
|
stringify: true // default is 'auto' // https://vite.dev/config/shared-options.html#json-stringify
|
||||||
|
},
|
||||||
|
esbuild: {
|
||||||
|
jsxFactory: 'h',
|
||||||
|
jsxFragment: 'Fragment',
|
||||||
|
jsxInject: `import React from 'react'`
|
||||||
|
},
|
||||||
|
logLevel: 'debug', // default is `info`
|
||||||
|
clearScreen: false, // default is `true`
|
||||||
|
envDir: '.',
|
||||||
|
appType: 'spa',
|
||||||
|
server: {
|
||||||
|
host: 'localhost',
|
||||||
|
allowedHosts: ['localhost', '.phenixrts.com'],
|
||||||
|
port: 5173,
|
||||||
|
open: true,
|
||||||
|
hmr: true,
|
||||||
|
fs: {
|
||||||
|
strict: true,
|
||||||
|
deny: ['.env', '.env.*', '*.{crt,pem}', '**/.git/**'] // default is `['.env', '.env.*', '*.{crt,pem}', '**/.git/**']`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
target: ['es2020', 'chrome80', 'firefox78', 'safari14'],
|
||||||
|
outDir: 'dist',
|
||||||
|
assetsDir: 'assets',
|
||||||
|
assetsInlineLimit: 4096, // default is `4096` ~ 4KiB
|
||||||
|
cssCodeSplit: true,
|
||||||
|
minify: isProductionMode,
|
||||||
|
cssMinify: isProductionMode,
|
||||||
|
sourcemap: !isProductionMode,
|
||||||
|
manifest: false, // default is `false`<-- https://vite.dev/config/build-options.html#build-manifest ,
|
||||||
|
ssrManifest: false,
|
||||||
|
ssr: false,
|
||||||
|
emitAssets: false,
|
||||||
|
terserOptions: {},
|
||||||
|
emptyOutDir: true,
|
||||||
|
copyPublicDir: true,
|
||||||
|
reportCompressedSize: true,
|
||||||
|
chunkSizeWarningLimit: 500,
|
||||||
|
watch: null
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
VitePluginReact(),
|
||||||
|
ViteBabelPlugin({
|
||||||
|
babelConfig: {
|
||||||
|
plugins: ['transform-amd-to-commonjs', 'babel-plugin-styled-components']
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
} satisfies UserConfig;
|
||||||
|
});
|
||||||
1128
Web/WebSocket/websocket/bun.lock
Normal file
1128
Web/WebSocket/websocket/bun.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,16 +11,16 @@
|
|||||||
"build:types": "npm run build -w @techniker-me/websocket-shared-types",
|
"build:types": "npm run build -w @techniker-me/websocket-shared-types",
|
||||||
"dev": "npm run dev --workspaces --if-present",
|
"dev": "npm run dev --workspaces --if-present",
|
||||||
"dev:server": "npm run dev -w @techniker-me/websocket-server",
|
"dev:server": "npm run dev -w @techniker-me/websocket-server",
|
||||||
"dev:frontend": "npm run dev -w @techniker-me/websocket-frontend",
|
"dev:frontend:vanilla": "npm run dev -w @techniker-me/websocket-frontend",
|
||||||
"dev:all": "concurrently \"npm run dev:server\" \"npm run dev:frontend\"",
|
|
||||||
"clean": "npm run clean --workspaces --if-present",
|
"clean": "npm run clean --workspaces --if-present",
|
||||||
"lint": "npm run lint --workspaces --if-present",
|
"lint": "npm run lint --workspaces --if-present",
|
||||||
"typecheck": "npm run typecheck --workspaces --if-present",
|
"typecheck": "npm run typecheck --workspaces --if-present",
|
||||||
"start": "npm run build:types && npm run dev:all"
|
"start": "npm run build:types && npm run dev:all"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "5.9.2",
|
"concurrently": "8.2.2",
|
||||||
"concurrently": "8.2.2"
|
"prettier": "3.6.2",
|
||||||
|
"typescript": "5.9.2"
|
||||||
},
|
},
|
||||||
"author": "Alexander Zinn"
|
"author": "Alexander Zinn"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
"typecheck": "tsc"
|
"typecheck": "tsc"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "~5.8.3"
|
"typescript": "~5.9.2"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,3 +39,5 @@ export interface ExtendedWebSocket {
|
|||||||
isOpen(): boolean;
|
isOpen(): boolean;
|
||||||
isClosed(): boolean;
|
isClosed(): boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Nullable<T> = T | null;
|
||||||
|
|||||||
Reference in New Issue
Block a user