chore: dox++
This commit is contained in:
parent
935e0a0054
commit
fc83c21bb6
4
TODO.md
4
TODO.md
|
@ -21,7 +21,7 @@
|
|||
- [x] Rename all hooks to dot-first notation; rewrite `lookupFlecks()`.
|
||||
- [x] ensureUniqueReduction moved into invokeMerge
|
||||
- [x] `bootstrap({without: ['badplatform']})` should be handled by passing `{platforms: ['!badplatform']}`
|
||||
- [ ] static documentation site generator
|
||||
- [x] documentation site generator
|
||||
- [ ] config validation
|
||||
- [ ] hints for hook types
|
||||
- [ ] user redux server hydrate fails if no user in req
|
||||
|
@ -31,7 +31,7 @@
|
|||
- [ ] @babel/register@7.18.x has a bug
|
||||
- [ ] `$flecks/db/sequelize` should be `$flecks/db.sequelize`
|
||||
- [x] `url()` in styles breaks HMR
|
||||
- [ ] 2 underscores for `FLECKS_ENV` variables
|
||||
- [x] 2 underscores for `FLECKS_ENV` variables
|
||||
- [x] flecks add
|
||||
|
||||
# Next
|
||||
|
|
|
@ -39,9 +39,7 @@ const {
|
|||
throw new Error(`@flecks/create-app: invalid app name: ${errors.join(', ')}`);
|
||||
}
|
||||
const destination = join(FLECKS_CORE_ROOT, app);
|
||||
if (!app.startsWith('@')) {
|
||||
app = `@${app}/monorepo`;
|
||||
}
|
||||
const name = app.startsWith('@') ? app : `@${app}/monorepo`;
|
||||
if (!await testDestination(destination)) {
|
||||
const error = new Error(
|
||||
`@flecks/create-app: destination '${destination} already exists: aborting`,
|
||||
|
@ -49,13 +47,16 @@ const {
|
|||
error.code = 129;
|
||||
throw error;
|
||||
}
|
||||
const fileTree = await move(app, join(__dirname, 'template'), 'app', flecks);
|
||||
const fileTree = await move(name, join(__dirname, 'template'), 'app', flecks);
|
||||
fileTree.pipe(
|
||||
'build/flecks.yml',
|
||||
transform((chunk, encoding, done, stream) => {
|
||||
const yml = loadYml(chunk);
|
||||
yml['@flecks/core/server'] = {packageManager};
|
||||
stream.push(dumpYml(yml, {sortKeys: true}));
|
||||
if ('npm' !== packageManager) {
|
||||
yml['@flecks/core/server'] = {packageManager};
|
||||
}
|
||||
yml['@flecks/core'] = {id: app};
|
||||
stream.push(dumpYml(yml, {forceQuotes: true, sortKeys: true}));
|
||||
done();
|
||||
}),
|
||||
);
|
||||
|
@ -67,6 +68,6 @@ const {
|
|||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
await program.parseAsync(process.argv);
|
||||
})();
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
"@babel/types": "^7.17.0",
|
||||
"@flecks/core": "^2.0.3",
|
||||
"@webpack-cli/serve": "^2.0.5",
|
||||
"add-asset-html-webpack-plugin": "^6.0.0",
|
||||
"add-asset-html-webpack-plugin": "^3.2.2",
|
||||
"assert": "^2.1.0",
|
||||
"autoprefixer": "^9.8.6",
|
||||
"before-build-webpack": "^0.2.13",
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
---
|
||||
title: Adding a fleck
|
||||
description: Add a fleck to your application to extend its functionality.
|
||||
---
|
||||
|
||||
# Adding a fleck
|
||||
|
||||
`@flecks/web` is a fleck that builds and serves a webpage. You can add it to your application
|
||||
using flecks:
|
||||
|
||||
```bash
|
||||
npx flecks add @flecks/web
|
||||
```
|
||||
|
||||
Now, if you run `npm start`, you'll see a line in the output:
|
||||
|
||||
```
|
||||
@flecks/web/server/http HTTP server up @ 0.0.0.0:32340!
|
||||
```
|
||||
|
||||
## Finally... a white page?
|
||||
|
||||
If you visit `localhost:32340` in your browser, you should now see... a blank white page! Don't fret
|
||||
though; if you open the devtools in your browser, you will see a little messaging from your
|
||||
application that will look something like:
|
||||
|
||||
```
|
||||
[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.
|
||||
[HMR] Waiting for update signal from WDS...
|
||||
flecks client v2.0.3 loading runtime...
|
||||
```
|
||||
|
||||
This is a good sign! This means we successfully added a web server with HMR enabled by default.
|
||||
Oh, the possibilities...
|
||||
|
||||
## Proceed with the hooking
|
||||
|
||||
How does flecks know to start the web server when the application starts? Great question! This is
|
||||
accomplished through the use of hooks. You'll see how to configure that hook in the next section.
|
||||
|
||||
For now, we'll learn how to create our own fleck and do a little hooking of our own. Take that, dad!
|
115
website/docs/adding-flecks.mdx
Normal file
115
website/docs/adding-flecks.mdx
Normal file
|
@ -0,0 +1,115 @@
|
|||
---
|
||||
title: Adding flecks
|
||||
description: Add flecks to your application to extend its functionality.
|
||||
---
|
||||
|
||||
# Adding flecks
|
||||
|
||||
`@flecks/web` is a fleck that builds and serves a webpage. You can add it to your application
|
||||
using the CLI:
|
||||
|
||||
```bash
|
||||
npx flecks add @flecks/web
|
||||
```
|
||||
|
||||
Now, if you run `npm start`, you'll see a line in the output:
|
||||
|
||||
```
|
||||
@flecks/web/server/http HTTP server up @ 0.0.0.0:32340!
|
||||
```
|
||||
|
||||
## Finally... a white page?
|
||||
|
||||
If you visit `localhost:32340` in your browser, you should now see... a blank white page! Don't fret
|
||||
though; if you open the devtools in your browser, you will see a little messaging from your
|
||||
application that will look something like:
|
||||
|
||||
```
|
||||
[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.
|
||||
[HMR] Waiting for update signal from WDS...
|
||||
flecks client v2.0.3 loading runtime...
|
||||
```
|
||||
|
||||
This is a good sign! This means we successfully added a web server with HMR enabled by default.
|
||||
Oh, the possibilities...
|
||||
|
||||
## Proceed with the hooking
|
||||
|
||||
Let's make our fleck `say-hello` hook into `@flecks/web` client to do something when the client
|
||||
comes up (e.g. the browser loads the page).
|
||||
|
||||
```javascript title="packages/say-hello/src/index.js"
|
||||
export const hooks = {
|
||||
// highlight-start
|
||||
'@flecks/web/client.up': async () => {
|
||||
window.document.body.append('hello world');
|
||||
},
|
||||
// highlight-end
|
||||
'@flecks/server.up': async (flecks) => {
|
||||
const {id} = flecks.get('@flecks/core');
|
||||
process.stdout.write(` hello server: ID ${id}\n`);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Now, restart your application and refresh your website. Glorious, isn't it?
|
||||
|
||||

|
||||
|
||||
## Everything so far... plus Electron!
|
||||
|
||||
Let's add another core fleck. flecks ships with a core fleck `@flecks/electron`. This runs your
|
||||
application inside of an instance of [Electron](https://www.electronjs.org/). You'll add the fleck:
|
||||
|
||||
```bash
|
||||
npx flecks add @flecks/electron
|
||||
```
|
||||
|
||||
Then you'll update your `build/flecks.yml` like so:
|
||||
|
||||
```yml
|
||||
'@flecks/core':
|
||||
id: 'hello-world'
|
||||
'@flecks/electron': {}
|
||||
// highlight-start
|
||||
'@flecks/server':
|
||||
up:
|
||||
- '...'
|
||||
- '@flecks/web'
|
||||
- '@flecks/electron'
|
||||
// highlight-end
|
||||
'@flecks/web': {}
|
||||
'@hello-world/say-hello:./packages/say-hello/src': {}
|
||||
```
|
||||
|
||||
### ~~flecking~~ pecking order
|
||||
|
||||
We added some configuration to `@flecks/server`. The `up` key configures the order in which flecks
|
||||
are initialized when the server comes up. We make sure `@flecks/web` serves a webpage before
|
||||
`@flecks/electron` tries to visit it.
|
||||
|
||||
:::tip
|
||||
|
||||
`'...'` just means "everything else": if any other flecks implement that hook then they will run
|
||||
here in an **undefined** order. It is valid to provide entries both before and after `'...'`, but
|
||||
`'...'` must only appear one time per list.
|
||||
|
||||
The default configuration of
|
||||
`@flecks/server.up` is simply:
|
||||
|
||||
```yml
|
||||
'@flecks/server':
|
||||
up:
|
||||
- '...'
|
||||
```
|
||||
|
||||
However in this case the order of hook execution is undefined. That's why we configure it
|
||||
explicitly.
|
||||
|
||||
:::
|
||||
|
||||
Finally `npm start` and you will see something like this:
|
||||
|
||||

|
||||
|
||||
Isn't it beautiful? :relieved:
|
|
@ -5,8 +5,8 @@ description: Configure `build/flecks.yml` and your application.
|
|||
|
||||
# Configuration
|
||||
|
||||
You have a flecks application! ...but it doesn't do much. This is because a flecks application is
|
||||
composed of individual flecks and by default, your application will have only two flecks:
|
||||
You have a flecks application! ...but it doesn't do much. By default, your application will have
|
||||
only two flecks:
|
||||
`@flecks/core` and `@flecks/server`. Your `build/flecks.yml` file will look like this:
|
||||
|
||||
```yml title="build/flecks.yml"
|
||||
|
@ -20,24 +20,22 @@ For a deep dive of configurable core flecks, see
|
|||
|
||||
## `build/flecks.yml`
|
||||
|
||||
A good first configuration step is to set the ID of your application.
|
||||
Your flecks application stores its build configuration in a directory located at `build`. By
|
||||
default, there is a single file located there: `flecks.yml`. This is where all the individual
|
||||
flecks are configured.
|
||||
|
||||
Your application's ID is configured at the `id` key of `@flecks/core`'s configuration. To set your
|
||||
application's ID to `hello_world`, update your `build/flecks.yml` to look like this:
|
||||
Your application's ID is configured at the `id` key of `@flecks/core`'s configuration:
|
||||
|
||||
```yml title="build/flecks.yml"
|
||||
// highlight-start
|
||||
'@flecks/core':
|
||||
id: 'hello_world'
|
||||
id: 'hello-world'
|
||||
// highlight-end
|
||||
'@flecks/server': {}
|
||||
```
|
||||
|
||||
## Adding more
|
||||
Notice that the ID was set automatically by the app creation utility.
|
||||
|
||||
If you were studious enough to take a peek at [the generated configuration page](/docs/flecks/@flecks/dox/config)
|
||||
above, you may have noticed that there were a lot more flecks there than just the two in our
|
||||
application.
|
||||
## Moving forward
|
||||
|
||||
For instance, there is a `@flecks/web` fleck that turns your little old server application into one
|
||||
that can build and serve a webpage. We'll see how to add it in the next section.
|
||||
In the next section, we'll look at how to create a fleck.
|
||||
|
|
|
@ -4,30 +4,27 @@ description: A fleck is a module but also so much more.
|
|||
---
|
||||
|
||||
If you are following along from the previous getting started
|
||||
[configuration page](./configuration), you have an application with 3 flecks:
|
||||
[configuration page](./configuration), you have an application with 2 flecks:
|
||||
|
||||
- `@flecks/core`
|
||||
- `@flecks/server`
|
||||
- `@flecks/web`
|
||||
|
||||
<details>
|
||||
<summary>About that "3 flecks" thing...</summary>
|
||||
<summary>About that "2 flecks" thing...</summary>
|
||||
|
||||
Actually, your server application has 6 flecks at this point:
|
||||
Actually, your server application has **4 flecks** at this point:
|
||||
|
||||
- `@flecks/core`
|
||||
- `@flecks/core/server`
|
||||
- `@flecks/server`
|
||||
- `@flecks/server/server`
|
||||
- `@flecks/web`
|
||||
- `@flecks/web/server`
|
||||
|
||||
flecks will load the `[...]/server` fleck under any fleck that is loaded on the server. This is
|
||||
also the case when using `@flecks/web` which will automatically load `[...]/client` flecks
|
||||
which are only loaded in the browser. We'll be exploring this specifically in the next section.
|
||||
If you're intersted in diving deeper, see [the platforms concept page](#todo).
|
||||
|
||||
Some frameworks make it a little cheesier to work with isomorphic code, but the flecks
|
||||
Some frameworks make it a little more opaque to work with isomorphic code, but the flecks
|
||||
philosophy is that visibility is believability: you'll have to be explicit about which code
|
||||
runs where.
|
||||
</details>
|
||||
|
@ -63,7 +60,6 @@ After some output, you'll find your new fleck at `packages/say-hello`. Let's ins
|
|||
'@flecks/core':
|
||||
id: 'hello_world'
|
||||
'@flecks/server': {}
|
||||
'@flecks/web': {}
|
||||
// highlight-next-line
|
||||
'@hello-world/say-hello:./packages/say-hello/src': {}
|
||||
```
|
||||
|
@ -107,68 +103,53 @@ There is a source file at `packages/say-hello/src/index.js` but for now it's emp
|
|||
out a bit:
|
||||
|
||||
```javascript title="packages/say-hello/src/index.js"
|
||||
exports.hooks = {
|
||||
'@flecks/web/client.up': async () => {
|
||||
window.document.body.append('hello world');
|
||||
export const hooks = {
|
||||
'@flecks/server.up': async () => {
|
||||
process.stdout.write(' hello server\n');
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
Now, restart your application and visit your website. Glorious, isn't it?
|
||||
|
||||
## Everything so far... plus Electron!
|
||||
|
||||
Let's add another core fleck. flecks ships with a core fleck `@flecks/electron`. This runs your
|
||||
application inside of an instance of [Electron](https://www.electronjs.org/). You'll add the fleck:
|
||||
Now, restart your application:
|
||||
|
||||
```bash
|
||||
npx flecks add @flecks/electron
|
||||
npm run start
|
||||
```
|
||||
|
||||
Then you'll update your `build/flecks.yml` like so:
|
||||
You will be greeted by a line in the output:
|
||||
|
||||
```yml
|
||||
'@flecks/core':
|
||||
id: 'hello_world'
|
||||
'@flecks/electron': {}
|
||||
// highlight-start
|
||||
'@flecks/server':
|
||||
up:
|
||||
- '...'
|
||||
- '@flecks/web'
|
||||
- '@flecks/electron'
|
||||
// highlight-end
|
||||
'@flecks/web': {}
|
||||
'@hello-world/say-hello:./packages/say-hello/src': {}
|
||||
```terminal
|
||||
hello server
|
||||
```
|
||||
|
||||
### ~~flecking~~ pecking order
|
||||
### flecks injection
|
||||
|
||||
We added some configuration to `@flecks/server`. The `up` key configures the order in which flecks
|
||||
are initialized when the server comes up. We make sure `@flecks/web` serves a webpage before
|
||||
`@flecks/electron` tries to visit it.
|
||||
Hook implementations may receive arguments. After any arguments, the `flecks` instance is always
|
||||
passed.
|
||||
|
||||
:::tip
|
||||
`@flecks/server.up` doesn't pass any arguments, so the `flecks` instance is the first argument.
|
||||
Let's see how to use the instance to read some configuration:
|
||||
|
||||
`'...'` just means "everything else": if any other flecks implement that hook then they will run
|
||||
here. It is valid to provide entries both before and after `'...'`.
|
||||
|
||||
The default configuration of
|
||||
`@flecks/server.up` is simply:
|
||||
|
||||
```yml
|
||||
'@flecks/server':
|
||||
up:
|
||||
- '...'
|
||||
```javascript title="packages/say-hello/src/index.js"
|
||||
export const hooks = {
|
||||
'@flecks/server.up': async (flecks) => {
|
||||
const {id} = flecks.get('@flecks/core');
|
||||
process.stdout.write(` hello server: ID ${id}\n`);
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
However in this case the order of hook execution is undefined. That's why we configure it
|
||||
explicitly.
|
||||
This time, you will see:
|
||||
|
||||
```terminal
|
||||
hello server: ID hello-world
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
...or whatever your application's ID is. We're assuming you're following along from
|
||||
[the configuration page](./configuration).
|
||||
|
||||
:::
|
||||
|
||||
Finally `npm start` and you will see something like this:
|
||||
|
||||

|
||||
|
||||
Isn't it beautiful? :relieved:
|
||||
Next, we'll add and interact with some of the flecks shipped by default.
|
||||
|
|
|
@ -18,37 +18,35 @@ so:
|
|||
```
|
||||
|
||||
When running your application in different execution environments (say, production) you may want to
|
||||
override configuration such as this. This is done by using the a prefix followed by the
|
||||
fleck name and the key. The template literal for such a transformation would look like:
|
||||
override configuration such as this. This is done by like so:
|
||||
|
||||
### Syntax
|
||||
|
||||
```javascript
|
||||
`FLECKS_ENV__${Flecks.environmentalize(path)}__${key}`
|
||||
`FLECKS_ENV__${Flecks.environmentalize(fleck)}__${key}`
|
||||
```
|
||||
|
||||
:::note
|
||||
:::tip
|
||||
|
||||
Notice the `environmentalize` transformation: `@flecks/core`'s `id` key is set using the
|
||||
following variable:
|
||||
As an example, `@flecks/core`'s `id` key is set using the following variable:
|
||||
|
||||
```bash
|
||||
FLECKS_ENV__flecks_core__id=foobar
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>`Flecks.environmentalize`</summary>
|
||||
<summary>`Flecks.environmentalize` implementation</summary>
|
||||
```javascript
|
||||
static environmentalize(path) {
|
||||
return path
|
||||
// - `@flecks/core` -> `FLECKS_CORE`
|
||||
// - `@flecks/core` -> `flecks_core`
|
||||
.replace(/[^a-zA-Z0-9]/g, '_')
|
||||
.replace(/_*(.*)_*/, '$1');
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
Also note that the fleck path and key are still case-sensitive. This is because they are
|
||||
Note that the fleck path and key are still case-sensitive. This is because they are
|
||||
user-defined.
|
||||
|
||||
:::
|
||||
|
|
BIN
website/docs/flecks-web.png
Normal file
BIN
website/docs/flecks-web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -11,8 +11,8 @@ export default {
|
|||
items: [
|
||||
'installation',
|
||||
'configuration',
|
||||
'adding-a-fleck',
|
||||
'creating-a-fleck',
|
||||
'adding-flecks',
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue
Block a user