You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The itch app communicates with [butler](https://github.com/itchio/butler) via a JSON-RPC interface. Butler's API is defined in Go, and TypeScript type definitions are generated from this specification using a tool called `generous`.
4
+
5
+
## How It Works
6
+
7
+
Butler's API messages (requests, responses, and notifications) are defined in Go structs within the butler repository. The `generous` tool reads these definitions and generates corresponding TypeScript types and request creators that work with the `@itchio/butlerd` package.
8
+
9
+
The generated file lives at `src/common/butlerd/messages.ts` in the itch repository.
10
+
11
+
## Synchronizing Typings
12
+
13
+
When butler's API changes, the TypeScript typings in itch need to be regenerated to match. This ensures type safety when making butler calls from the app.
14
+
15
+
To regenerate the typings, ensure you have the butler repository checked out alongside itch:
16
+
17
+
```
18
+
parent/
19
+
├── butler/
20
+
└── itch/
21
+
```
22
+
23
+
Then run:
24
+
25
+
```bash
26
+
npm run sync-butler
27
+
```
28
+
29
+
This runs the generous generator from the butler repo and outputs the updated TypeScript definitions.
30
+
31
+
## When to Sync
32
+
33
+
You should regenerate the typings when:
34
+
35
+
- Butler adds new API endpoints
36
+
- Butler modifies existing request/response types
37
+
- Butler adds or changes notifications
38
+
- You're working with a newer version of butler that has API changes
Copy file name to clipboardExpand all lines: developing/getting-started.md
+39-67Lines changed: 39 additions & 67 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,42 +2,44 @@
2
2
3
3
itch is built in TypeScript and runs inside of Electron.
4
4
5
-
To get started, install the latest [node.js](https://nodejs.org/)
5
+
To get started, ensure you have a modern version of [node.js](https://nodejs.org/) installed.
6
6
7
-
> Linux distributions tend to ship outdated node.js versions
8
-
>
7
+
> Linux distributions may ship outdated node.js versions
9
8
> Use the nodesource [binary distributions](https://github.com/nodesource/distributions/) to get an up-to-date one.
10
9
11
10
Then, clone the [https://github.com/itchio/itch](https://github.com/itchio/itch) repository somewhere.
12
11
13
-
Install the javascript dependencies by running this command from within the `itch` directory you've just cloned:
12
+
Install the javascript dependencies by running the following command from within the `itch` directory you've just cloned:
14
13
15
14
```bash
16
15
$ npm install
17
16
```
18
17
19
-
> For native modules, you'll need a compiler toolchain: Visual Studio 2015 on Windows, gcc/clang on Linux/macOS. See the [node-gyp](https://github.com/nodejs/node-gyp) page for more information on this.
18
+
> For native modules, you'll need a compiler toolchain: Visual Studio 2015 on
19
+
> Windows, gcc/clang on Linux/macOS. See the
20
+
> [node-gyp](https://github.com/nodejs/node-gyp) page for more information on
21
+
> this.
20
22
21
23
Finally, start the app!
22
24
23
25
```bash
24
26
$ npm start
25
27
```
26
28
27
-
The first run will seem slow, because the compile cache is empty. Subsequent runs will be much faster.
28
-
29
29
## Environment
30
30
31
-
There are three environments in which the app can run: `development`, `test`, and `production`.
32
-
33
-
`development` is what you'll be using to develop the app. It includes warnings and tools that aren't in the other environments, such as:
34
-
35
-
* Hot module reloading
36
-
* React warnings
31
+
There are three environments in which the app can run: `development`, `test`,
32
+
and `production`.
37
33
38
-
`production` is what the app runs on when it's released as a package to end-users. It's a fast, no-nonsense environment, and it enables things like self-updates, locale updates, etc.
39
-
40
-
`test` looks a lot like `production` except that some things are disabled: logging, for instance, is suppressed. The app will also not exit by itself, but print a well-known string to the console, allowing the integration test runner to kill the app itself.
34
+
***`development`** is what you'll be using to develop the app. It includes warnings
35
+
and tools that aren't in the other environments, such as React warnings.
36
+
***`production`** is what the app runs on when it's released as a package to
37
+
end-users. It's a fast, no-nonsense environment, and it enables things like
38
+
self-updates, locale updates, etc.
39
+
***`test`** looks a lot like `production` except that some things are disabled:
40
+
logging, for instance, is suppressed. The app will also not exit by itself, but
41
+
print a well-known string to the console, allowing the integration test runner
42
+
to kill the app itself.
41
43
42
44
## App structure
43
45
@@ -66,12 +68,10 @@ All processes have a redux store, the **main** store is the reference, and the o
66
68
67
69
## Chrome Developer Tools \(renderer\)
68
70
69
-
Press `Shift-F12` to open the Chrome Developer Tools, to inspect the DOM, run arbitrary javascript code in the **chrome** side of the app, etc.
71
+
Press `Shift + F12` to open the Chrome Developer Tools, to inspect the DOM, run arbitrary javascript code in the **chrome** side of the app, etc.
70
72
71
73

72
74
73
-
> The React devtools are automatically installed in the `development` environment, although you'll need to reload the page after opening the devtools to see the tab.
74
-
75
75
If the app crashes before it gets a chance to install the keyboard shortcut,
76
76
you can `export DEVTOOLS=1` before starting the app so that they open as early as possible.
77
77
@@ -99,61 +99,28 @@ Note that pausing in the developer tools will freeze the whole app, so your OS m
99
99
100
100
## Compiling
101
101
102
-
TypeScript sources and static assets live in `src`. They're compiled and bundled by [webpack](https://webpack.js.org/).
103
-
104
-
In development, files are recompiled automatically and the chrome side is served over HTTP.
105
-
106
-
*`npm start` is not black magic, it just runs `develop.js` - feel free to look into it
107
-
108
-
In production, they're precompiled and packaged so that a lot of development dependencies are not included in the final builds.
109
-
110
-
### Hot module reload
102
+
TypeScript sources and static assets live in `src`. They're compiled and
103
+
bundled by [esbuild](https://esbuild.github.io/).
111
104
112
-
When the app is started in developent, it watches for file changes, and reloads parts of itself automatically. This mostly applies to the **renderer** side of the app, React components in particular.
113
-
114
-
By having your code editor and the app open side to side, you can quickly iterate on the looks of a React component.
105
+
In development, files are recompiled automatically, you can refresh the user
106
+
interface of the app to view the latest UI. Since the redux state is unchanged
107
+
on refresh you should be left off where you were. The easiest way to refresh
108
+
the UI is the open the Devtools (`Shift + F12`) and hit `Ctrl + r` with the
109
+
devtools focused.
115
110
116
111
## Code style
117
112
118
113
We use [prettier](https://www.npmjs.com/package/prettier) to make sure the codebase has a consistent style.
119
114
120
-
There's a pre-commit hook that formats staged files. It's powered by husky and [lint-staged](https://github.com/okonet/lint-staged), see the `package.json`
115
+
There's a pre-commit hook that formats staged files. It's powered by husky and
116
+
[lint-staged](https://github.com/okonet/lint-staged), see the `package.json`
121
117
for the configuration.
122
118
123
-
Some text editors have plug-ins for prettier, which can help you format on save. There are workspace settings for the [Visual Studio Code prettier plug-in](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) in the repository.
124
-
125
-
### Asynchronous code
119
+
Some text editors have plug-ins for prettier, which can help you format on
120
+
save. There are workspace settings for the [Visual Studio Code prettier
We use TypeScript's async/await support so that instead of writing this:
128
-
129
-
```typescript
130
-
function installSoftware (name:string) {
131
-
returndownload(name)
132
-
.then(() =>extract(name))
133
-
.then(() =>verify(name))
134
-
.catch((err) => {
135
-
// Uh oh, something happened
136
-
});
137
-
}
138
-
```
139
-
140
-
...we can write this:
141
-
142
-
```typescript
143
-
asyncfunction installSoftware (name:string) {
144
-
try {
145
-
awaitdownload(name);
146
-
awaitextract(name);
147
-
awaitverify(name);
148
-
} catch (err) {
149
-
// Uh oh, something happened
150
-
}
151
-
}
152
-
```
153
-
154
-
In development, async/await code is transformed using babel to bluebird promises, which in turn uses coroutines and has long stack traces support.
155
-
156
-
This lets us dive into issues that involve several promises awaiting each other. In production, they're left as-is, since both Node and Chrome now support async/await.
157
124
158
125
### React components
159
126
@@ -163,13 +130,18 @@ We have a `hook` function that allows writing fully type-checked connected compo
163
130
164
131
Look at `src/renderer/basics/` for simple examples.
165
132
133
+
> **Note:** We are in the proces of migrating to React Hooks and Functional Components. Use `React.memo` where possible.
134
+
166
135
### Styled components \(CSS\)
167
136
168
-
Most of the CSS styles in the app are handled by [styled-components](https://github.com/styled-components/styled-components).
This lets us handle theme switching, namespace and compose our styles easily.
171
141
172
-
Some text editor plug-ins, like [styled-components for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=jpoissonnier.vscode-styled-components) provide syntax highlighting for css blocks.
142
+
Some text editor plug-ins, like [styled-components for Visual Studio
Translations for the itch app are managed in a separate repository and contributed via Weblate. To update the app with the latest translations, you need to sync from the external repo.
4
+
5
+
## How It Works
6
+
7
+
Translations are stored in the [itch-i18n](https://github.com/itchio/itch-i18n) repository. Community members contribute translations through [Weblate](https://weblate.itch.zone), which commits changes to that repo.
8
+
9
+
The locale files (JSON) are copied into the itch app at `src/static/locales/`.
10
+
11
+
## Syncing Translations
12
+
13
+
Ensure you have the itch-i18n repository checked out alongside itch:
14
+
15
+
```
16
+
parent/
17
+
├── itch/
18
+
└── itch-i18n/
19
+
```
20
+
21
+
Then run the import script:
22
+
23
+
```bash
24
+
node release/import-i18n-strings.js
25
+
```
26
+
27
+
This deletes the existing `src/static/locales/` directory and copies the latest translations from `../itch-i18n/locales/`.
28
+
29
+
## When to Sync
30
+
31
+
You should sync translations when:
32
+
33
+
- Preparing a new release
34
+
- New translations have been added via Weblate
35
+
- You want to test recent translation updates locally
Copy file name to clipboardExpand all lines: developing/performance.md
+40-38Lines changed: 40 additions & 38 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,53 +18,55 @@ Get to know the tools. They're good.
18
18
19
19
In short:
20
20
21
-
*Only use `React.PureComponent`, always
22
-
* For connected components, use reselect \(createStructuredSelector, createSelector\) in `mapStateToProps`\(grep the codebase for examples\)
23
-
*Avoid `[]` or `{}` in `mapStateToProps`, do this instead:
21
+
*Use `React.memo` to wrap your functional components. It serves the same purpose as `React.PureComponent` but for functional components, preventing unnecessary re-renders by using a shallow comparison of props.
22
+
23
+
*For connected components, use hooks like `useSelector` from `react-redux` to listen only the least set of dependent values to avoid re-renders
*Anonymous functions or `this.something.bind(this)` create a new value every time, and will wreck `shouldComponentUpdate`.
43
+
*Avoid using anonymous functions in render when passing into sub-components so that they make take advantage of memoization. Instead, use stable references with `useCallback` which will return a memoized version of the callback that only changes if one of the dependencies has changed.
// In TypeScript, this is called an instance function
58
-
doStuff = () => {
52
+
};
53
+
54
+
// This will force MyComplexComponent to always re-render
55
+
return<MyComplexComponent onClick={doStuff}/>;
56
+
});
57
+
58
+
// Good practice
59
+
constGoodComponent=memo(() => {
60
+
constdoStuff=useCallback(() => {
59
61
// stuff.
60
-
}
62
+
}, []); // Dependencies array
61
63
62
-
render () {
63
-
// `this.doStuff` stays the same, won't trigger unnecessary renders
64
-
return<div onClick={this.doStuff}/>
65
-
}
66
-
}
64
+
// Memoized `doStuff` won't trigger unnecessary renders when GoodComponent is re-rerendered
65
+
return<div onClick={doStuff}/>;
66
+
});
67
67
```
68
68
69
-
`PureComponent` uses shallow comparison in `shouldComponentUpdate`. If you pass a new object/array/function reference on every render, the comparison will always return false and trigger unnecessary re-renders. By using stable references (module-level constants, instance methods), you let React's pure rendering optimizations work properly.
69
+
By using hooks and keeping function references stable with `useCallback`, you
70
+
allow React's memoization strategies to optimize your component rendering. This
71
+
helps in performance gains by reducing unnecessary rendering.
0 commit comments