Skip to content

Commit

Permalink
create react vite electron example (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
matiaspompilio authored Oct 19, 2023
1 parent a839c55 commit 2e27632
Show file tree
Hide file tree
Showing 37 changed files with 12,267 additions and 0 deletions.
15 changes: 15 additions & 0 deletions examples/react-vite-electron-example/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# http://editorconfig.org

root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
1 change: 1 addition & 0 deletions examples/react-vite-electron-example/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_APP_BASE_URL=
15 changes: 15 additions & 0 deletions examples/react-vite-electron-example/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
node_modules/

# Ignore artifacts:
coverage/
dist/
dev-dist/
public/
__mocks__/

jest.config.js
postcss.config.js
*.d.ts

src/theme/
tools/
35 changes: 35 additions & 0 deletions examples/react-vite-electron-example/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module.exports = {
extends: ['plugin:react/recommended', 'plugin:prettier/recommended', 'plugin:@typescript-eslint/recommended'],
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 2020,
ecmaFeatures: {
jsx: true,
},
sourceType: 'module',
tsconfigRootDir: __dirname,
},
env: {
browser: true,
commonjs: true,
node: true,
es2020: true,
'jest/globals': true,
},
plugins: ['react', 'jsx-a11y', 'import', 'jest'],
ignorePatterns: ['.eslintrc.js'],
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
rules: {
'react/prop-types': 'off',
'no-restricted-imports': [
'error',
{
patterns: ['@/features/*/*'],
},
],
},
},
],
};
7 changes: 7 additions & 0 deletions examples/react-vite-electron-example/.markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"MD041": false,
"MD042": false,
"MD004": false,
"MD013": false,
"MD033": false
}
1 change: 1 addition & 0 deletions examples/react-vite-electron-example/.node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.15.0
14 changes: 14 additions & 0 deletions examples/react-vite-electron-example/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
node_modules/

# Ignore artifacts:
coverage/
dist/
dev-dist/
public/
__mocks__/

jest.config.js
postcss.config.js
*.d.ts

src/theme/
7 changes: 7 additions & 0 deletions examples/react-vite-electron-example/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 2,
};
55 changes: 55 additions & 0 deletions examples/react-vite-electron-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# react-vite-electron-example Frontend

This project was generated using [create-awesome-node-app](https://www.npmjs.com/package/create-awesome-node-app). **DON'T USE THIS TEMPLATE AS IT!** Generate yours using the command and following the options in the interactive menu. Check the docs for more information!

## Features

- ⚡️ **Instant HMR** - use [Vite](https://vitejs.dev/) on dev (no more refresh!)
- ⚛ React - [React](https://reactjs.org/) is used for UI
- 🦾 [TypeScript](https://www.typescriptlang.org/) - type safe

## Extra documentation

You can find useful information such as project structure, available scripts and much more in the [docs](./docs) folder!

## Pre-packed

### Dev tools

- [TypeScript](https://www.typescriptlang.org/)
- [eslint](https://eslint.org/) - Linting utility for JavaScript and JSX
- [prettier](https://prettier.io/) - Opinionated code formatter
- [husky](https://www.npmjs.com/package/husky) - Git hooks made easy
- [lint-staged](https://www.npmjs.com/package/lint-staged) - Run linters against staged git files and don't let 💩 slip into your code base!

## Quickstart

```sh
fnm use
npm install
npm run dev
```

## Development

While developing, you will probably rely mostly on `npm run start`; however, there are additional scripts at your disposal:

| `npm run <script>` | Description |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| `dev` | Serves your app at for local development |
| `format` | Formats the project using [Prettier](https://prettier.io/) |
| `lint` | [Lints](http://stackoverflow.com/questions/8503559/what-is-linting) the project for potential errors |
| `lint:fix` | Lints the project and [fixes all correctable errors](http://eslint.org/docs/user-guide/command-line-interface.html#fix) |

## Production

Available scripts:

| `npm run <script>` | Description |
| ------------------ | --------------------------------------------------------------------- |
| `preview` | Serves your app using your production ready setup (`.env.production`) |
| `build` | Builds the application to `dist/` |

## Contributing

You can report bugs, request features and create Pull Requests in the [Create-Node-App/cna-templates](https://github.com/Create-Node-App/cna-templates) repository!
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# 🧱 Components And Styling

## Components Best Practices

### Colocate things as close as possible to where it's being used

Keep components, functions, styles, state, etc. as close as possible to the component where it's being used. This will not only make your codebase more readable and easier to understand but it will also improve your application performance since it will reduce redundant re-renders on state updates.

### Avoid large components with nested rendering functions

Do not add multiple rendering functions inside your application, this gets out of control pretty quickly. What you should do instead is if there is a piece of UI that can be considered as a unit, is to extract it in a separate component.

```javascript
// this is very difficult to maintain as soon as the component starts growing
function Component() {
function renderItems() {
return <ul>...</ul>;
}
return <div>{renderItems()}</div>;
}

// extract it in a separate component
function Items() {
return <ul>...</ul>;
}

function Component() {
return (
<div>
<Items />
</div>
);
}
```

### Stay consistent

### Limit the number of props a component is accepting as input

If your component is accepting too many props you might consider splitting it into multiple components or use the composition technique via children or slots.

### Abstract shared components into a component library

For larger projects, it is a good idea to build abstractions around all the shared components. It makes the application more consistent and easier to maintain. Identify repetitions before creating the components to avoid wrong abstractions.

It is a good idea to wrap 3rd party components as well in order to adapt them to the application's needs. It might be easier to make the underlying changes in the future without affecting the application's functionality.

## Component libraries

Every project requires some UI components such as modals, tabs, sidebars, menus, etc. Instead of building those from scratch, you might want to use some of the existing, battle-tested component libraries.

### Fully featured component libraries

These component libraries come with their components fully styled.

- [Chakra UI](https://chakra-ui.com/) - great library with probably the best developer experience, allows very fast prototyping with decent design defaults. Plenty of components that are very customizable and flexible with accessibility already configured out of the box.

- [AntD](https://ant.design/) - another great component library that has a lot of different components. Best suitable for creating admin dashboards. However, it might be a bit difficult to change the styles in order to adapt them to a custom design.

- [MUI](https://mui.com/) - the most popular component library for React. Has a lot of different components. Can be used as a styled solution by implementing Material Design or as unstyled headless component library.

### Headless component libraries

These component libraries come with their components unstyled. If you have a specific design system to implement, it might be easier and better solution to go with headless components that come unstyled than to adapt a styled components library such as Material UI to your needs. Some good options are:

- [Reakit](https://reakit.io/)
- [Headless UI](https://headlessui.dev/)
- [Radix UI](https://www.radix-ui.com/)
- [react-aria](https://react-spectrum.adobe.com/react-aria/)

## Styling Solutions

There are multiple ways to style a react application. Some good options are:

- [tailwind](https://tailwindcss.com/)
- [styled-components](https://styled-components.com/)
- [emotion](https://emotion.sh/docs/introduction)
- [stitches](https://stitches.dev/)
- [vanilla-extract](https://github.com/seek-oss/vanilla-extract)
- [CSS modules](https://github.com/css-modules/css-modules)
- [linaria](https://github.com/callstack/linaria)

## Good combinations

Some good combinations of component library + styling

- [Chakra UI](https://chakra-ui.com/) + [emotion](https://emotion.sh/docs/introduction) - The best choice for most applications
- [Headless UI](https://headlessui.dev/) + [tailwind](https://tailwindcss.com/)
- [Radix UI](https://www.radix-ui.com/) + [stitches](https://stitches.dev/)
43 changes: 43 additions & 0 deletions examples/react-vite-electron-example/docs/PERFORMANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 🚄 Performance

## Code Splitting

Code splitting is a technique of splitting production JavaScript into smaller files, thus allowing the application to be only partially downloaded. Any unused code will not be downloaded until it is required by the application.

Most of the time code splitting should be done on the routes level, but can also be used for other lazy loaded parts of application.

Do not code split everything as it might even worsen your application's performance.

## Component and state optimizations

- Do not put everything in a single state. That might trigger unnecessary re-renders. Instead split the global state into multiple stores according to where it is being used.

- Keep the state as close as possible to where it is being used. This will prevent re-rendering components that do not depend on the updated state.

- If you have a piece of state that is initialized by an expensive computation, use the state initializer function instead of executing it directly because the expensive function will be run only once as it is supposed to. e.g:

```javascript
import { useState } from 'react';

// instead of this which would be executed on every re-render:
const [state, setState] = useState(myExpensiveFn());

// prefer this which is executed only once:
const [state, setState] = useState(() => myExpensiveFn());
```

- If you develop an application that requires the state to track many elements at once, you might consider state management libraries with atomic updates such as [recoil](https://recoiljs.org/) or [jotai](https://jotai.pmnd.rs/).

- If your application is expected to have frequent updates that might affect performance, consider switching from runtime styling solutions ([Chakra UI](https://chakra-ui.com/), [emotion](https://emotion.sh/docs/introduction), [styled-components](https://styled-components.com/) that generate styles during runtime) to zero runtime styling solutions ([tailwind](https://tailwindcss.com/), [linaria](https://github.com/callstack/linaria), [vanilla-extract](https://github.com/seek-oss/vanilla-extract), [CSS modules](https://github.com/css-modules/css-modules) which generate styles during build time).

## Image optimizations

Consider lazy loading images that are not in the viewport.

Use modern image formats such as WEBP for faster image loading.

Use `srcset` to load the most optimal image for the clients screen size.

## Web vitals

Since Google started taking web vitals in account when indexing websites, you should keep an eye on web vitals scores from [Lighthouse](https://web.dev/measure/) and [Pagespeed Insights](https://pagespeed.web.dev/).
55 changes: 55 additions & 0 deletions examples/react-vite-electron-example/docs/PROJECT_CONFIGURATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# ⚙️ Project Configuration

The application has been bootstrapped using `Creae Vite App` for simplicity reasons. It allows us to create applications quickly without dealing with a complex tooling setup such as bundling, transpiling etc.

You should always configure and use the following tools:

## ESLint

ESLint is a linting tool for JavaScript. By providing specific configuration defined in the`.eslintrc` file it prevents developers from making silly mistakes in their code and enforces consistency in the codebase.

[ESLint Configuration](../.eslintrc)

## Prettier

This is a great tool for formatting code. It enforces a consistent code style across your entire codebase. By utilizing the "format on save" feature in your IDE you can automatically format the code based on the configuration provided in the `.prettierrc` file. It will also give you good feedback when something is wrong with the code. If the auto-format doesn't work, something is wrong with the code.

[Prettier Configuration](../.prettierrc)

## TypeScript

ESLint is great for catching some of the bugs related to the language, but since JavaScript is a dynamic language ESLint cannot check data that run through the applications, which can lead to bugs, especially on larger projects. That is why TypeScript should be used. It is very useful during large refactors because it reports any issues you might miss otherwise. When refactoring, change the type declaration first, then fix all the TypeScript errors throughout the project and you are done. One thing you should keep in mind is that TypeScript does not protect your application from failing during runtime, it only does type checking during build time, but it increases development confidence drastically anyways. Here is a [great resource on using TypeScript with React](https://react-typescript-cheatsheet.netlify.app/).

## Husky

Husky is a tool for executing git hooks. Use Husky to run your code validations before every commit, thus making sure the code is in the best shape possible at any point of time and no faulty commits get into the repo. It can run linting, code formatting and type checking, etc. before it allows pushing the code. You can check how to configure it [here](https://typicode.github.io/husky/#/?id=usage).

## Absolute imports

Absolute imports should always be configured and used because it makes it easier to move files around and avoid messy import paths such as `../../../Component`. Wherever you move the file, all the imports will remain intact. Here is how to configure it:

For JavaScript (`jsconfig.json`) projects:

```json
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
```

For TypeScript (`tsconfig.json`) projects:

```json
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
```

[Paths Configuration](../tsconfig.json)

It is also possible to define multiple paths for various folders(such as `@/components`, `@/hooks`, etc.), but using `@/*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `src/components/MyComponent` can be accessed using `@/components/MyComponents`.
Loading

0 comments on commit 2e27632

Please sign in to comment.