Skip to content

Commit f953aff

Browse files
committed
More general docs cleanup
1 parent ba8b61f commit f953aff

File tree

9 files changed

+225
-143
lines changed

9 files changed

+225
-143
lines changed

src/content/docs/dev/setup.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ moonlight requires [Node.js](https://nodejs.org) 22 and [pnpm](https://pnpm.io)
1010
- Clone the repository: `git clone https://github.com/moonlight-mod/moonlight.git`
1111
- Install dependencies: `pnpm install`.
1212
- Build the project: `pnpm run build`.
13-
- For working on moonlight, a watch mode is available with `pnpm run dev`.
13+
- For working on moonlight, a watch mode is available with `pnpm run dev`. Remember that you must [restart the command in some scenarios](/ext-dev/pitfalls#restarting-dev-mode-is-required-in-some-scenarios).
1414

1515
For more information on project structure, [see the dedicated page](/dev/project-structure).
1616

src/content/docs/ext-dev/api.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ The global types are available [here](https://github.com/moonlight-mod/moonlight
2121

2222
## Extension libraries
2323

24-
These libraries are built into moonlight as [core extensions](/dev/core-extensions). Remember to [add the extension dependency](/ext-dev/cookbook#using-another-extension-as-a-library) and [add the module dependency](/ext-dev/webpack#webpack-module-dependencies) before using these libraries.
24+
These libraries are built into moonlight as [core extensions](/dev/core-extensions). See [here](/ext-dev/webpack#importing-other-webpack-modules) for an example on using them.
25+
26+
:::caution
27+
Remember to add the modules you use as a dependency for your [extension](/ext-dev/manifest/#dependencies) and [module](/ext-dev/webpack#webpack-module-dependencies).
28+
:::
2529

2630
### App Panels
2731

src/content/docs/ext-dev/cookbook.md

Lines changed: 63 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,92 +5,50 @@ sidebar:
55
order: 3
66
---
77

8-
## Exporting from your extension
9-
10-
On the web target (`index.ts`), you can export patches, Webpack modules, and styles:
11-
12-
```ts
13-
import type { ExtensionWebExports } from "@moonlight-mod/types";
14-
15-
export const patches: ExtensionWebExports["patches"] = [];
16-
export const webpackModules: ExtensionWebExports["webpackModules"] = {};
17-
export const styles: ExtensionWebExports["styles"] = [];
18-
```
19-
20-
All exports are optional.
21-
228
## Extension entrypoints
239

24-
Extensions can load in three different environments:
25-
26-
- In the browser (the "web" environment where Discord lives): `index.ts` & Webpack modules
27-
- On the Node.js side, where DiscordNative and such live: `node.ts`
28-
- On the host, with little sandboxing and access to Electron APIs: `host.ts`
29-
30-
These map to the renderer, preload script, and main process in Electron terminology. The term "browser" is used to refer to the moonlight browser extension, while "web" refers to both the desktop and browser platforms.
10+
Some extensions need to go beyond the scope of the Discord web application and interact with the native parts of the client. To help with this, extensions can load in one or more environments:
3111

32-
Most extensions only need to run code in the browser. Use the Node environment if you need access to system APIs, like the filesystem or creating processes. Use the Host environment if you need to use the Electron API.
12+
- The "web" environment (the browser where the web app runs): `index.ts` & Webpack modules
13+
- The "Node" environment (where DiscordNative runs, with access to Node.js APIs): `node.ts`
14+
- The "host" environment (with little sandboxing and access to Electron APIs): `host.ts`
3315

34-
Remember that [you cannot directly import Node.js modules](/ext-dev/pitfalls#web-vs-nodejs), and should [share code with `moonlight.getNatives`](#sharing-code-between-nodejs-and-the-web).
16+
These map to the renderer, preload script, and main process in Electron terminology. In moonlight internals, the term "browser" is used to refer to the moonlight browser extension, while "web" refers to the web application that runs on the desktop app and browser site.
3517

36-
## Sharing code between Node.js and the web
18+
Most extensions only run in the web environment, where the majority of the Discord client code executes in. However, extensions can run in the other environments for access to extra APIs when needed. Use system APIs as little as possible, and be mindful about [security concerns](https://www.electronjs.org/docs/latest/tutorial/context-isolation#security-considerations).
3719

38-
Make a `node.ts` file:
20+
Extensions can export APIs from the Node environment and import them from the web environment using `moonlight.getNatives`:
3921

4022
```ts title="node.ts"
41-
module.exports.doSomething = () => {
42-
console.log("Doing something...");
43-
};
23+
export function doSomething() {
24+
// insert some Node.js-specific code here
25+
}
4426
```
4527

46-
Then, use it from your extension:
47-
48-
```ts title="index.ts"
28+
```ts title="webpackModules/something.ts"
4929
const natives = moonlight.getNatives("your extension ID");
50-
// natives will be null if using moonlight in the browser
51-
natives?.doSomething();
30+
natives.doSomething();
5231
```
5332

54-
Remember to [restart the dev server](/ext-dev/pitfalls#restarting-dev-mode-is-required-in-some-scenarios).
33+
Remember to [restart the dev server](/ext-dev/pitfalls#restarting-dev-mode-is-required-in-some-scenarios) after creating `node.ts`, and that [you cannot directly import node.ts](/ext-dev/pitfalls#web-vs-nodejs).
5534

56-
## Using another extension as a library
57-
58-
Mark the extension as a dependency of your extension:
59-
60-
```json title="manifest.json"
61-
{
62-
"dependencies": ["markdown"]
63-
}
64-
```
65-
66-
Mark the Webpack module as a dependency of your own Webpack module:
67-
68-
```ts title="index.ts"
69-
export const webpackModules: ExtensionWebExports["webpackModules"] = {
70-
someModule: {
71-
dependencies: [
72-
{
73-
ext: "markdown",
74-
id: "markdown"
75-
}
76-
]
77-
}
78-
};
79-
```
35+
## Exporting from your extension
8036

81-
Then, import the Webpack module:
37+
On the web target (`index.ts`), you can export [patches](/ext-dev/webpack#patching), [Webpack modules](/ext-dev/webpack#webpack-module-insertion), and CSS styles:
8238

83-
```ts title="webpackModules/someModule.ts"
84-
import * as markdown from "@moonlight-mod/wp/markdown_markdown";
39+
```ts
40+
import type { ExtensionWebExports } from "@moonlight-mod/types";
8541

86-
markdown.addRule(/* ... */);
42+
export const patches: ExtensionWebExports["patches"] = [];
43+
export const webpackModules: ExtensionWebExports["webpackModules"] = {};
44+
export const styles: ExtensionWebExports["styles"] = [];
8745
```
8846

89-
Remember to [restart the dev server](/ext-dev/pitfalls#restarting-dev-mode-is-required-in-some-scenarios).
47+
All exports are optional. If you aren't exporting anything from this file (e.g. your extension works entirely on the Node or host environments), you can delete `index.ts`.
9048

91-
## Making a custom React component
49+
## Using React
9250

93-
Mark React as a dependency of your own Webpack module:
51+
Create a [Webpack module](/ext-dev/webpack#webpack-module-insertion) with a `.tsx` file extension, then mark React as a [module dependency](/ext-dev/webpack#webpack-module-dependencies):
9452

9553
```ts title="index.ts"
9654
export const webpackModules: ExtensionWebExports["webpackModules"] = {
@@ -104,7 +62,7 @@ export const webpackModules: ExtensionWebExports["webpackModules"] = {
10462
};
10563
```
10664

107-
Then, import React from [mappings](/ext-dev/mappings):
65+
In the module, import React from [mappings](/ext-dev/mappings):
10866

10967
```tsx title="webpackModules/element.tsx"
11068
import React from "@moonlight-mod/wp/react";
@@ -114,18 +72,17 @@ export default function MyElement() {
11472
}
11573
```
11674

117-
React [must be imported when using JSX](/ext-dev/pitfalls#using-jsx).
75+
You can use this React component in a [patch](/ext-dev/webpack#patching) or through an [extension library](/ext-dev/api#app-panels). React must be imported into the scope [when using JSX](/ext-dev/pitfalls#using-jsx).
11876

119-
## Using Spacepack to find code dynamically
77+
## Using Flux
12078

121-
```ts
122-
import spacepack from "@moonlight-mod/wp/spacepack_spacepack";
123-
const { something } = spacepack.findByCode(/* ... */)[0].exports;
124-
```
79+
Discord internally maintains a heavily-modified fork of [Flux](https://github.com/facebookarchive/flux). Various state and events in the client are managed with Flux.
12580

126-
Remember to add your find to [your extension dependencies](/ext-dev/webpack#webpack-module-insertion) and [declare Spacepack as a dependency](#using-another-extension-as-a-library).
81+
### Interacting with Flux events
12782

128-
## Interacting with Flux events
83+
Flux events contain a type (e.g. `MESSAGE_CREATE`) and their associated data. They function similarly to [the Discord gateway](https://discord.com/developers/docs/events/gateway) (and some gateway events have Flux equivalents), but they are two separate concepts, and there are client-specific Flux events.
84+
85+
To interact with Flux events, mark `discord/Dispatcher` as a [module dependency](/ext-dev/webpack#webpack-module-dependencies), then import it from [mappings](/ext-dev/mappings) in your Webpack module:
12986

13087
```ts
13188
import Dispatcher from "@moonlight-mod/wp/discord/Dispatcher";
@@ -138,21 +95,47 @@ Dispatcher.subscribe("MESSAGE_CREATE", (event: any) => {
13895
// Block all events (don't actually do this)
13996
Dispatcher.addInterceptor((event) => {
14097
console.log(event.type);
141-
return true;
98+
return true; // return `true` to block, `false` to pass through
14299
});
143100
```
144101

145-
## Interacting with Flux stores
102+
### Interacting with Flux stores
103+
104+
Flux stores contain application state and dispatch/receive events. Most Flux stores use the same central Flux dispatcher (`discord/Dispatcher`).
105+
106+
To interact with Flux stores, use the [Common](/ext-dev/api#common) extension library by adding it as a dependency to your [extension](/ext-dev/manifest#dependencies) and [module](/ext-dev/webpack#webpack-module-dependencies):
146107

147108
```ts
148109
import { UserStore } from "@moonlight-mod/wp/common_stores";
149110

150111
console.log(UserStore.getCurrentUser());
151112
```
152113

153-
## Modifying message content before it is sent
114+
Flux stores can be used in React components with [the `useStateFromStores` hook](https://github.com/moonlight-mod/mappings/blob/main/src/mappings/discord/packages/flux/useStateFromStores.ts).
115+
116+
## Using slash commands
154117

155-
Remember to add `commands` to your manifest's dependencies and `{ext: "commands", id: "commands"}` to your Webpack module's dependencies.
118+
Slash commands can be registered with the [Commands](/ext-dev/api#commands) extension library. Remember to add the Commands extension as a [extension](/ext-dev/manifest#dependencies) and [module](/ext-dev/webpack#webpack-module-dependencies) dependency.
119+
120+
```ts
121+
import Commands from "@moonlight-mod/wp/commands_commands";
122+
import { InputType, CommandType } from "@moonlight-mod/types/coreExtensions/commands";
123+
124+
Commands.registerCommand({
125+
id: "myCoolCommand",
126+
description: "(insert witty example description here)",
127+
inputType: InputType.BUILT_IN,
128+
type: CommandType.CHAT,
129+
options: [],
130+
execute: () => {
131+
// do something here
132+
}
133+
});
134+
```
135+
136+
### Modifying message content before it is sent
137+
138+
The legacy command system can also be used to replace text in messages before they are sent.
156139

157140
```ts
158141
import Commands from "@moonlight-mod/wp/commands_commands";
@@ -164,9 +147,8 @@ Commands.registerLegacyCommand("unique-id", {
164147
// something based on a specific string.
165148
match: /.*/,
166149
action: (content, context) => {
167-
// Modify the content
168-
169-
return {content};
150+
// modify the content here
151+
return { content };
170152
}
171153
})
172154
```

src/content/docs/ext-dev/getting-started.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ sidebar:
55
order: 1
66
---
77

8+
:::note
9+
This page is for developers who want to make their own extensions. If you're looking for documentation on using moonlight itself, see [here](/using/getting-started).
10+
:::
11+
812
## Requirements
913

1014
- [Node.js](https://nodejs.org) 22 or later
@@ -86,7 +90,7 @@ Right now, your extension doesn't do much. Let's go over what each file does:
8690
- In `index.ts`, your extension exports its [patches](/ext-dev/webpack#patching) and [Webpack modules](/ext-dev/webpack#webpack-module-insertion). Make sure to export every patch and Webpack module you create, or else moonlight won't load them.
8791
- If you open the Discord settings menu, you should see the "User Settings" section has been renamed to "hacked by (your extension ID) lol". This was edited by the patch in `index.ts`, which modifies Discord to insert and replace custom code.
8892
- In the `webpackModules` folder, there are multiple Webpack modules, which is where most of your extension's code lives. Right now, all they do is log to the console.
89-
- In `node.ts`, your extension runs [in the Node environment](/ext-dev/cookbook/#extension-entrypoints), where you can access the filesystem or spawn extra processes. Most extensions don't need to use this, though.
93+
- In `node.ts`, your extension runs [in the Node environment](/ext-dev/cookbook#extension-entrypoints), where you can access the filesystem or spawn extra processes. Most extensions don't need to use this, though.
9094
- In `env.d.ts` (at the root of the repository), your extension's Webpack module is declared to let you import it directly. Make sure to update this file when you add or remove Webpack modules, but don't delete it entirely.
9195

9296
We suggest keeping these examples around for experimentation, but you should delete what you aren't using before you publish your extension. Most extensions don't use `node.ts`, for example.
@@ -96,7 +100,7 @@ We suggest keeping these examples around for experimentation, but you should del
96100
Run `pnpm run dev` to enter watch mode. When you make changes to your extension, the extension will automatically be rebuilt, and you can reload your client (`Ctrl+R`) to load the new version of your extension.
97101

98102
:::note
99-
Watch mode will need to be restarted if you edit the extension manifest, add/remove an entrypoint, or add/remove a Webpack module. If you delete an extension, entrypoint, or Webpack module, you should run `pnpm run clean` to clean up the remaining build output.
103+
Watch mode will need to be restarted when making certain changes or adding/removing new entrypoints. See [here](/ext-dev/pitfalls#restarting-dev-mode-is-required-in-some-scenarios) for more information.
100104
:::
101105

102106
Try changing one of the logger messages, or maybe edit the example patch. Play around a bit and see what happens!

src/content/docs/ext-dev/helpful-exts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Helpful extensions
3-
description: This is a list of helpful extensions that can be used to aid extension development.
3+
description: Helpful extensions that can be used to aid extension development
44
sidebar:
55
order: 5
66
---

src/content/docs/ext-dev/manifest.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,20 @@ This is an example manifest, with every value filled in:
5454
}
5555
```
5656

57+
## Dependencies
58+
59+
Some extensions depend on other extensions to function, like using an extension as a library. Your extension should always declare the extensions it depends on in its manifest:
60+
61+
```json title="manifest.json"
62+
{
63+
"dependencies": ["markdown"]
64+
}
65+
```
66+
67+
Additionally, when using Webpack modules from other extensions, you must [declare a dependency for your module](/ext-dev/webpack#webpack-module-dependencies) too.
68+
69+
moonlight will implicitly enable the extensions that your extension depends on. For extensions that aren't locally present (e.g. libraries present on an extension repository), Moonbase will prompt the user to install the required dependencies.
70+
5771
## Settings
5872

5973
There are many settings types that you can use to configure your extension in Moonbase. The types for these are available [here](https://github.com/moonlight-mod/moonlight/blob/main/packages/types/src/config.ts).

src/content/docs/ext-dev/mappings.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ import Dispatcher from "@moonlight-mod/wp/discord/Dispatcher";
3030
const Dispatcher = require("discord/Dispatcher").default;
3131
```
3232

33-
Remember to [add the module as a dependency](/ext-dev/webpack#webpack-module-dependencies) to your Webpack module.
33+
Remember to [add the module as a dependency](/ext-dev/webpack#webpack-module-dependencies) to your Webpack module. Unlike extension libraries, mappings are built into moonlight, and do not need to be added to your extension's manifest.
3434

3535
## Mappings stability
3636

3737
The mappings repository only proxies existing Discord modules and exports. As such, if Discord removes a module or export, or a module is not properly remapped, the mapping will fail and your extension may break.
3838

39-
You should structure your code with the expectation that imported modules or exports may randomly fail. Use the [ErrorBoundary](/ext-dev/api#common) component provided by moonlight to safely catch errors in your UI code.
39+
Exports and types in the mappings repository may change or be removed if Discord removes it from their own source code. In this scenario, moonlight developers are forced to remove the mapping, and we do not have the ability to bring a module back.
40+
41+
See [here](/ext-dev/webpack#discord-module-stability) for more information on module stability.

src/content/docs/ext-dev/pitfalls.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,24 @@ sidebar:
77

88
## Web vs Node.js
99

10-
Node.js code cannot be imported directly from the web side. You must use `moonlight.getNatives`. See [the cookbook](/ext-dev/cookbook#sharing-code-between-nodejs-and-the-web) for how to access Node.js exports.
10+
Node.js code cannot be imported directly from the web environment. To share code between the two environments, use `moonlight.getNatives`. See [the cookbook](/ext-dev/cookbook#extension-entrypoints) for more information.
1111

1212
## Webpack require is not Node.js require
1313

14-
The `require` function used in Webpack modules and patches is not the same as the function in Node.js. Instead, it lets you require other Webpack modules by their IDs.
15-
16-
If you have a Webpack module you want to load, [you can require it by its ID](/ext-dev/webpack#importing-other-webpack-modules).
14+
The `require` function used in Webpack modules and patches is not the same as the function in Node.js. Instead, it's specific to Webpack, and only works inside of Webpack modules. See [here](/ext-dev/webpack#importing-other-webpack-modules) for more information.
1715

1816
## The web entrypoint is not a Webpack module
1917

20-
You cannot use Webpack modules inside of `index.ts`, because it is loaded before Webpack is initialized. Instead, [create your own Webpack module](/ext-dev/webpack#webpack-module-insertion) and use that.
18+
You cannot use Webpack modules inside of `index.ts`, because it is loaded before Webpack is initialized. Instead, [create your own Webpack module](/ext-dev/webpack#webpack-module-insertion) and use that instead.
2119

2220
## Webpack modules only load when required
2321

2422
By default, Webpack modules will not load unless they are required by another module or the `entrypoint` flag is set. If you need a module to run as soon as possible, [set the entrypoint flag](/ext-dev/webpack#webpack-module-insertion).
2523

24+
## Using ESM features
25+
26+
ESM-specific features (like top-level `await`) are not supported in Webpack modules or the Node or Host environments. The `index.ts` file in your extension (and *only* that file) can be compiled to ESM by [modifying your build script](https://github.com/moonlight-mod/esbuild-config/blob/8e91f1db1773380bc140c9ca3e140c30ecf5bcc3/src/factory.ts#L75).
27+
2628
## Spacepack findByCode matching itself
2729

2830
When using the `findByCode` function in Spacepack while inside of a Webpack module, you can sometimes accidentally match yourself. It is suggested to fragment the string in source but have it evaluate to the same string:
@@ -35,7 +37,7 @@ Note that esbuild will merge string concatenation, so you must be creative!
3537

3638
## Using JSX
3739

38-
[JSX](https://react.dev/learn/writing-markup-with-jsx) (and its TypeScript version, TSX) is an extension of JavaScript that allows you to write HTML-like syntax in your code. The default configuration of the build script is to convert the JSX to `React.createElement` calls:
40+
[JSX](https://react.dev/learn/writing-markup-with-jsx) (and its TypeScript version, TSX) is an extension of JavaScript that allows you to write HTML-like syntax in your code. [Webpack modules](/ext-dev/webpack#webpack-module-insertion) with a `.tsx` filename can use JSX directly. The default configuration of the build script is to convert the JSX to `React.createElement` calls:
3941

4042
```tsx
4143
const myElement = <span>Hi!</span>;
@@ -50,7 +52,7 @@ import React from "@moonlight-mod/wp/react";
5052
const myElement = <span>Hi!</span>;
5153
```
5254

53-
Remember to add React to [your extension dependencies](/ext-dev/webpack#webpack-module-insertion).
55+
More information on using React in extensions can be found [here](/ext-dev/cookbook#using-react). Remember to add React to [your module dependencies](/ext-dev/webpack#webpack-module-insertion).
5456

5557
## Using the wrong moonlight global
5658

0 commit comments

Comments
 (0)