@foxford/den 3.1.0 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.mdx +66 -15
- package/adapter.cjs +1 -1
- package/adapter.d.cts +1 -1
- package/adapter.d.ts +1 -1
- package/adapter.js +1 -1
- package/bin/den.cjs +88 -0
- package/bin/den.d.cts +2 -0
- package/bin/den.d.ts +2 -0
- package/bin/den.js +88 -0
- package/builder/index.cjs +12 -0
- package/builder/index.d.cts +124 -0
- package/builder/index.d.ts +124 -0
- package/builder/index.js +12 -0
- package/{chunk-KJ6NDOOL.js → chunk-3RX2OSUL.js} +1 -25
- package/{chunk-HJO26HIQ.js → chunk-6FNC3XMI.js} +4 -0
- package/{chunk-CZVYVNLI.cjs → chunk-6QV4L6R2.cjs} +1 -25
- package/chunk-A6ZPAM6Z.cjs +26 -0
- package/chunk-LW7IN57F.cjs +358 -0
- package/chunk-MCMYOVGT.js +358 -0
- package/{chunk-PZVUKTZG.js → chunk-MCN4GFEQ.js} +4 -2
- package/{chunk-XHYR3SGG.cjs → chunk-T5QVCXVB.cjs} +5 -1
- package/chunk-TPBI6TOU.js +26 -0
- package/{chunk-7M5OAOQ4.js → chunk-TPHJUDHG.js} +20 -4
- package/{chunk-P4QJCHMM.cjs → chunk-Z5BL4DJA.cjs} +11 -9
- package/{chunk-6ZFVV3AV.cjs → chunk-ZOU6W6ZQ.cjs} +31 -15
- package/{define-repository-MDEWHqM7.d.cts → define-repository-CwAXed2X.d.cts} +1 -1
- package/{define-repository-Ca62_YCy.d.ts → define-repository-q_T4hqeP.d.ts} +1 -1
- package/{define-slot-Dil8Kr1A.d.ts → define-slot-Cngzae6i.d.ts} +1 -1
- package/{define-slot-BKvArA02.d.cts → define-slot-DYNCLDJY.d.cts} +1 -1
- package/define.cjs +6 -4
- package/define.d.cts +3 -3
- package/define.d.ts +3 -3
- package/define.js +6 -4
- package/den.js +60 -0
- package/{descriptor-DZDNH7R5.d.ts → descriptor-DQ6Gi7A_.d.ts} +31 -3
- package/{descriptor-h0JE9jFx.d.cts → descriptor-Dujg_1on.d.cts} +31 -3
- package/index.cjs +23 -22
- package/index.d.cts +7 -6
- package/index.d.ts +7 -6
- package/index.js +4 -3
- package/island/index.cjs +6 -5
- package/island/index.d.cts +13 -6
- package/island/index.d.ts +13 -6
- package/island/index.js +4 -3
- package/package.json +52 -26
- package/{routes-CWpIqVAM.d.ts → routes-0uXJ0fux.d.ts} +1 -1
- package/{routes-BqIoqbt1.d.cts → routes-B0hDrkiF.d.cts} +1 -1
- package/serve/index.cjs +11 -10
- package/serve/index.d.cts +4 -4
- package/serve/index.d.ts +4 -4
- package/serve/index.js +4 -3
- package/server-render-CocWXQKC.d.cts +48 -0
- package/server-render-CocWXQKC.d.ts +48 -0
- package/{types-COwVwgzE.d.cts → types-Dx5qGiwk.d.cts} +1 -1
- package/{types-COwVwgzE.d.ts → types-Dx5qGiwk.d.ts} +1 -1
- package/{view-adapter-CPI8056c.d.ts → view-adapter-B4gEb-ms.d.ts} +4 -50
- package/{view-adapter-D2597RJZ.d.cts → view-adapter-DJ7yB6Ml.d.cts} +4 -50
- package/den-serve.js +0 -146
package/README.mdx
CHANGED
|
@@ -80,7 +80,7 @@ routes: [
|
|
|
80
80
|
```ts
|
|
81
81
|
import { renderApp } from '@foxford/den/island'
|
|
82
82
|
|
|
83
|
-
const { status, html, state, head, headHtml, redirect } = await renderApp(app, {
|
|
83
|
+
const { status, html, state, head, headHtml, redirect, assets } = await renderApp(app, {
|
|
84
84
|
pathname: '/legal/general',
|
|
85
85
|
search: '?from=footer',
|
|
86
86
|
context: { cookies, headers }, // реквизиты браузерного запроса
|
|
@@ -89,7 +89,9 @@ const { status, html, state, head, headHtml, redirect } = await renderApp(app, {
|
|
|
89
89
|
|
|
90
90
|
`status` — исход запроса: `200` значит «вот страница», всё остальное значит, что страницы по
|
|
91
91
|
этому адресу нет, и тело такого ответа выбирает хост. `state` едет в документ и гидрирует
|
|
92
|
-
остров в браузере, `headHtml` — стили, собранные во время рендера.
|
|
92
|
+
остров в браузере, `headHtml` — стили, собранные во время рендера. `assets` — ссылки на
|
|
93
|
+
initial-чанки клиентской сборки, их подключает хост; байты приложение не отдаёт ни в одном
|
|
94
|
+
транспорте.
|
|
93
95
|
|
|
94
96
|
### Вклад в документ
|
|
95
97
|
|
|
@@ -126,17 +128,19 @@ export class ContentPageVM extends ViewModel<State> {
|
|
|
126
128
|
## Сетевой транспорт: то же самое по HTTP
|
|
127
129
|
|
|
128
130
|
Приложение поднимается отдельным сервисом **без единой строки своего серверного кода** —
|
|
129
|
-
дескриптор тот же, что и в процессе хоста.
|
|
131
|
+
дескриптор тот же, что и в процессе хоста. Точку входа процесса выпускает `den build`
|
|
132
|
+
(см. «Сборка приложения»), поэтому прод это голая нода:
|
|
130
133
|
|
|
131
134
|
```jsonc
|
|
132
135
|
// package.json приложения
|
|
133
136
|
"scripts": {
|
|
134
|
-
"dev": "
|
|
135
|
-
"
|
|
137
|
+
"dev": "den dev",
|
|
138
|
+
"build": "den build",
|
|
139
|
+
"start": "node build/server.mjs"
|
|
136
140
|
}
|
|
137
141
|
```
|
|
138
142
|
|
|
139
|
-
|
|
143
|
+
Рантайм вокруг дескриптора отдаёт три ручки:
|
|
140
144
|
|
|
141
145
|
| Ручка | Ответ |
|
|
142
146
|
| --- | --- |
|
|
@@ -184,14 +188,9 @@ export default (instance) => {
|
|
|
184
188
|
}
|
|
185
189
|
```
|
|
186
190
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
"start": "den-serve build/index.js --configure ./configure.js --port 3342"
|
|
191
|
-
},
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
Запуск с инструментацией: `NODE_OPTIONS='--import ./instrument.js' pnpm start`.
|
|
191
|
+
Такое расширение объявляется в конфиге приложения полем `server.configure` — своего серверного
|
|
192
|
+
кода по-прежнему ноль. Запуск с инструментацией:
|
|
193
|
+
`NODE_OPTIONS='--import ./instrument.js' pnpm start`.
|
|
195
194
|
|
|
196
195
|
Если сервер нужен свой — общий порт с чужими ручками, свой порядок плагинов, — берите плагин
|
|
197
196
|
и монтируйте куда угодно, хоть под префиксом:
|
|
@@ -211,6 +210,56 @@ await instance.listen({ port: 3342 })
|
|
|
211
210
|
`serveApp` поверх плагина добавляет логирование запросов (в терминах `@foxford/logger`, корень —
|
|
212
211
|
имя приложения, рендер дольше порога уходит в `warn`) и закрытие по `SIGTERM`/`SIGINT`.
|
|
213
212
|
|
|
213
|
+
## Сборка приложения: `den build`
|
|
214
|
+
|
|
215
|
+
Приложение объявляет дескриптор и `den.config.ts`. Конфиг сборщика, вход гидрации и точку входа
|
|
216
|
+
процесса писать не нужно — их собирает команда.
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
// den.config.ts
|
|
220
|
+
import { defineAppConfig } from '@foxford/den/build'
|
|
221
|
+
import { react } from '@foxford/den-react/preset'
|
|
222
|
+
|
|
223
|
+
export default defineAppConfig({
|
|
224
|
+
preset: react({ babel: { plugins: [['babel-plugin-styled-components', { ssr: true }]] } }),
|
|
225
|
+
server: {
|
|
226
|
+
setup: () => installServerDom(),
|
|
227
|
+
render: (tree, render) => ({ head: sheet.getStyleTags(), html: render(sheet.collectStyles(tree)) }),
|
|
228
|
+
container: (c) => c.bind(HttpConfigToken).toValue({ baseUrl: process.env.API_ORIGIN }),
|
|
229
|
+
configure: (instance) => Sentry.setupFastifyErrorHandler(instance),
|
|
230
|
+
noExternal: ['@foxford/ui', 'styled-components'],
|
|
231
|
+
},
|
|
232
|
+
})
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
`den build [--root <каталог>] [--base <префикс>]` выпускает три выхода, `den dev` — то же плюс
|
|
236
|
+
подъём процесса и пересборка на изменение исходников:
|
|
237
|
+
|
|
238
|
+
| Выход | Что внутри | Кто потребляет |
|
|
239
|
+
| --- | --- | --- |
|
|
240
|
+
| `build/client` | браузерный бандл и манифест | браузер, по ссылкам из ответа рендера |
|
|
241
|
+
| `build/server` | дескриптор с вплавленными серверными кусками конфига | хост, импортом в своём процессе |
|
|
242
|
+
| `build/server.mjs` | тот же дескриптор под сетевым рантаймом | `node build/server.mjs` |
|
|
243
|
+
|
|
244
|
+
**Про фреймворк команда не знает.** Чем собирать и чем оживлять, приносит пресет из пакета
|
|
245
|
+
адаптера, поэтому приложение на другом фреймворке подключается своим пресетом и в командах не
|
|
246
|
+
меняется ничего.
|
|
247
|
+
|
|
248
|
+
**Конфиг — вход СБОРКИ, а не рантайм-сосед дескриптора.** Серверные куски вплавляются в
|
|
249
|
+
серверный выход, и дескриптор остаётся декларацией — иначе он не годился бы входом клиентской
|
|
250
|
+
сборки: сборщик не выкинет сбор стилей, пока объект дескриптора на него ссылается. Соседом
|
|
251
|
+
конфиг быть не может: приложение в процессе хоста импортируется хостом целиком, конфига у хоста
|
|
252
|
+
нет, и до движка серверные куски не доехали бы.
|
|
253
|
+
|
|
254
|
+
**Движок в серверный выход не вбандливается.** У него модульное состояние, app-контейнер —
|
|
255
|
+
синглтон, и своя копия внутри приложения даёт второй контейнер: приложение биндит в один,
|
|
256
|
+
а резолвит из другого. Симптом — «view-слой не объявлен» на приложении, которое его объявило.
|
|
257
|
+
Клиентский выход наоборот собирается целиком: браузер голых имён модулей не резолвит.
|
|
258
|
+
|
|
259
|
+
**Настройку процесса дожидается движок.** `server.setup` зовётся один раз на процесс до первого
|
|
260
|
+
рендера, включая приложение в процессе хоста, где обвязки нет и дождаться было бы некому.
|
|
261
|
+
Упавшая настройка не повторяется: процесс сломан, и прятать это за случайным успехом нельзя.
|
|
262
|
+
|
|
214
263
|
## Подпути
|
|
215
264
|
|
|
216
265
|
| Подпуть | Что там |
|
|
@@ -219,4 +268,6 @@ await instance.listen({ port: 3342 })
|
|
|
219
268
|
| `@foxford/den/define` | те же `define*` без сайд-эффекта установки резолвера |
|
|
220
269
|
| `@foxford/den/adapter` | шов резолва для адаптеров хостов |
|
|
221
270
|
| `@foxford/den/island` | остров: жизненный цикл, шов `renderApp`, порт `ViewAdapter` |
|
|
222
|
-
| `@foxford/den/serve` | сетевой транспорт: `serveApp`, `appPlugin
|
|
271
|
+
| `@foxford/den/serve` | сетевой транспорт: `serveApp`, `appPlugin` |
|
|
272
|
+
| `@foxford/den/build` | конфиг приложения и сборка: `defineAppConfig`, `buildApp` |
|
|
273
|
+
| `@foxford/den/bin` | точка входа команды `den` |
|
package/adapter.cjs
CHANGED
package/adapter.d.cts
CHANGED
package/adapter.d.ts
CHANGED
package/adapter.js
CHANGED
package/bin/den.cjs
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkLW7IN57Fcjs = require('../chunk-LW7IN57F.cjs');
|
|
5
|
+
require('../chunk-A6ZPAM6Z.cjs');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var _chunkT5QVCXVBcjs = require('../chunk-T5QVCXVB.cjs');
|
|
9
|
+
|
|
10
|
+
// src/bin/cli.ts
|
|
11
|
+
var USAGE = `den <\u043A\u043E\u043C\u0430\u043D\u0434\u0430> [\u043E\u043F\u0446\u0438\u0438]
|
|
12
|
+
|
|
13
|
+
\u041A\u043E\u043C\u0430\u043D\u0434\u044B:
|
|
14
|
+
build \u0441\u043E\u0431\u0440\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435: \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u0438\u0439 \u0432\u044B\u0445\u043E\u0434, \u0441\u0435\u0440\u0432\u0435\u0440\u043D\u044B\u0439 \u0434\u0435\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0440 \u0438 \u0442\u043E\u0447\u043A\u0443
|
|
15
|
+
\u0432\u0445\u043E\u0434\u0430 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 (build/client, build/server, build/server.mjs)
|
|
16
|
+
dev \u0442\u043E \u0436\u0435 \u043F\u043B\u044E\u0441 \u043F\u043E\u0434\u044A\u0451\u043C \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \u0438 \u043F\u0435\u0440\u0435\u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u0430 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u043E\u0432
|
|
17
|
+
|
|
18
|
+
\u041E\u043F\u0446\u0438\u0438:
|
|
19
|
+
--root <\u043A\u0430\u0442\u0430\u043B\u043E\u0433> \u043A\u043E\u0440\u0435\u043D\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u043A\u0430\u0442\u0430\u043B\u043E\u0433)
|
|
20
|
+
--base <\u043F\u0440\u0435\u0444\u0438\u043A\u0441> \u043F\u0440\u0435\u0444\u0438\u043A\u0441 \u0430\u0434\u0440\u0435\u0441\u043E\u0432 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u043E\u0432: \u0432 \u043F\u0440\u043E\u0434\u0435 CDN, \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u043A\u0435 \u0440\u0430\u0437\u0432\u044F\u0437\u043A\u0430
|
|
21
|
+
\u0443 \u0445\u043E\u0441\u0442\u0430 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E /)
|
|
22
|
+
-h, --help \u044D\u0442\u0430 \u0441\u043F\u0440\u0430\u0432\u043A\u0430
|
|
23
|
+
`;
|
|
24
|
+
function parseArgs(argv) {
|
|
25
|
+
const options = {};
|
|
26
|
+
let command;
|
|
27
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
28
|
+
const arg = argv[i];
|
|
29
|
+
if (arg === "-h" || arg === "--help") {
|
|
30
|
+
return { help: true, options: {} };
|
|
31
|
+
}
|
|
32
|
+
if (arg === "--root" || arg === "--base") {
|
|
33
|
+
i += 1;
|
|
34
|
+
options[arg.slice(2)] = argv[i];
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if ((arg == null ? void 0 : arg.startsWith("-")) === true) {
|
|
38
|
+
throw new Error(`\u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043E\u043F\u0446\u0438\u044F ${arg}`);
|
|
39
|
+
}
|
|
40
|
+
if (command !== void 0) {
|
|
41
|
+
throw new Error("\u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043E\u0434\u043D\u0430");
|
|
42
|
+
}
|
|
43
|
+
command = arg;
|
|
44
|
+
}
|
|
45
|
+
return { command, options };
|
|
46
|
+
}
|
|
47
|
+
function fail(message) {
|
|
48
|
+
process.stderr.write(`den: ${message}
|
|
49
|
+
|
|
50
|
+
${USAGE}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
function run(argv) {
|
|
54
|
+
return _chunkT5QVCXVBcjs.__async.call(void 0, this, null, function* () {
|
|
55
|
+
var _a;
|
|
56
|
+
let parsed;
|
|
57
|
+
try {
|
|
58
|
+
parsed = parseArgs(argv);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
61
|
+
}
|
|
62
|
+
if (parsed.help === true) {
|
|
63
|
+
process.stdout.write(USAGE);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { command, options } = parsed;
|
|
67
|
+
if (command === void 0) {
|
|
68
|
+
fail("\u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0430");
|
|
69
|
+
}
|
|
70
|
+
const target = { base: options["base"], root: (_a = options["root"]) != null ? _a : process.cwd() };
|
|
71
|
+
if (command === "build") {
|
|
72
|
+
yield _chunkLW7IN57Fcjs.buildApp.call(void 0, target);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (command === "dev") {
|
|
76
|
+
yield _chunkLW7IN57Fcjs.devApp.call(void 0, target);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
fail(`\u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \xAB${command}\xBB`);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/bin/den.ts
|
|
84
|
+
run(process.argv.slice(2)).catch((error) => {
|
|
85
|
+
process.stderr.write(`den: ${error instanceof Error ? error.message : String(error)}
|
|
86
|
+
`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
package/bin/den.d.cts
ADDED
package/bin/den.d.ts
ADDED
package/bin/den.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildApp,
|
|
3
|
+
devApp
|
|
4
|
+
} from "../chunk-MCMYOVGT.js";
|
|
5
|
+
import "../chunk-TPBI6TOU.js";
|
|
6
|
+
import {
|
|
7
|
+
__async
|
|
8
|
+
} from "../chunk-6FNC3XMI.js";
|
|
9
|
+
|
|
10
|
+
// src/bin/cli.ts
|
|
11
|
+
var USAGE = `den <\u043A\u043E\u043C\u0430\u043D\u0434\u0430> [\u043E\u043F\u0446\u0438\u0438]
|
|
12
|
+
|
|
13
|
+
\u041A\u043E\u043C\u0430\u043D\u0434\u044B:
|
|
14
|
+
build \u0441\u043E\u0431\u0440\u0430\u0442\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435: \u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u0438\u0439 \u0432\u044B\u0445\u043E\u0434, \u0441\u0435\u0440\u0432\u0435\u0440\u043D\u044B\u0439 \u0434\u0435\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0440 \u0438 \u0442\u043E\u0447\u043A\u0443
|
|
15
|
+
\u0432\u0445\u043E\u0434\u0430 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 (build/client, build/server, build/server.mjs)
|
|
16
|
+
dev \u0442\u043E \u0436\u0435 \u043F\u043B\u044E\u0441 \u043F\u043E\u0434\u044A\u0451\u043C \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \u0438 \u043F\u0435\u0440\u0435\u0441\u0431\u043E\u0440\u043A\u0430 \u043D\u0430 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0435 \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u043E\u0432
|
|
17
|
+
|
|
18
|
+
\u041E\u043F\u0446\u0438\u0438:
|
|
19
|
+
--root <\u043A\u0430\u0442\u0430\u043B\u043E\u0433> \u043A\u043E\u0440\u0435\u043D\u044C \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0442\u0435\u043A\u0443\u0449\u0438\u0439 \u043A\u0430\u0442\u0430\u043B\u043E\u0433)
|
|
20
|
+
--base <\u043F\u0440\u0435\u0444\u0438\u043A\u0441> \u043F\u0440\u0435\u0444\u0438\u043A\u0441 \u0430\u0434\u0440\u0435\u0441\u043E\u0432 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u043E\u0432: \u0432 \u043F\u0440\u043E\u0434\u0435 CDN, \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u043A\u0435 \u0440\u0430\u0437\u0432\u044F\u0437\u043A\u0430
|
|
21
|
+
\u0443 \u0445\u043E\u0441\u0442\u0430 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E /)
|
|
22
|
+
-h, --help \u044D\u0442\u0430 \u0441\u043F\u0440\u0430\u0432\u043A\u0430
|
|
23
|
+
`;
|
|
24
|
+
function parseArgs(argv) {
|
|
25
|
+
const options = {};
|
|
26
|
+
let command;
|
|
27
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
28
|
+
const arg = argv[i];
|
|
29
|
+
if (arg === "-h" || arg === "--help") {
|
|
30
|
+
return { help: true, options: {} };
|
|
31
|
+
}
|
|
32
|
+
if (arg === "--root" || arg === "--base") {
|
|
33
|
+
i += 1;
|
|
34
|
+
options[arg.slice(2)] = argv[i];
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if ((arg == null ? void 0 : arg.startsWith("-")) === true) {
|
|
38
|
+
throw new Error(`\u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043E\u043F\u0446\u0438\u044F ${arg}`);
|
|
39
|
+
}
|
|
40
|
+
if (command !== void 0) {
|
|
41
|
+
throw new Error("\u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u043E\u0434\u043D\u0430");
|
|
42
|
+
}
|
|
43
|
+
command = arg;
|
|
44
|
+
}
|
|
45
|
+
return { command, options };
|
|
46
|
+
}
|
|
47
|
+
function fail(message) {
|
|
48
|
+
process.stderr.write(`den: ${message}
|
|
49
|
+
|
|
50
|
+
${USAGE}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
function run(argv) {
|
|
54
|
+
return __async(this, null, function* () {
|
|
55
|
+
var _a;
|
|
56
|
+
let parsed;
|
|
57
|
+
try {
|
|
58
|
+
parsed = parseArgs(argv);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
fail(error instanceof Error ? error.message : String(error));
|
|
61
|
+
}
|
|
62
|
+
if (parsed.help === true) {
|
|
63
|
+
process.stdout.write(USAGE);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { command, options } = parsed;
|
|
67
|
+
if (command === void 0) {
|
|
68
|
+
fail("\u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0430");
|
|
69
|
+
}
|
|
70
|
+
const target = { base: options["base"], root: (_a = options["root"]) != null ? _a : process.cwd() };
|
|
71
|
+
if (command === "build") {
|
|
72
|
+
yield buildApp(target);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (command === "dev") {
|
|
76
|
+
yield devApp(target);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
fail(`\u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u0430\u044F \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \xAB${command}\xBB`);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// src/bin/den.ts
|
|
84
|
+
run(process.argv.slice(2)).catch((error) => {
|
|
85
|
+
process.stderr.write(`den: ${error instanceof Error ? error.message : String(error)}
|
|
86
|
+
`);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunkLW7IN57Fcjs = require('../chunk-LW7IN57F.cjs');
|
|
6
|
+
require('../chunk-A6ZPAM6Z.cjs');
|
|
7
|
+
require('../chunk-T5QVCXVB.cjs');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.buildApp = _chunkLW7IN57Fcjs.buildApp; exports.defineAppConfig = _chunkLW7IN57Fcjs.defineAppConfig; exports.devApp = _chunkLW7IN57Fcjs.devApp;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { a as ServerRender } from '../server-render-CocWXQKC.cjs';
|
|
2
|
+
import { Container } from '@foxford/ioc';
|
|
3
|
+
import { FastifyInstance } from 'fastify';
|
|
4
|
+
import { PluginOption } from 'vite';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Пресет фреймворка: чем собирать его исходники и чем оживлять фрагмент в браузере.
|
|
8
|
+
*
|
|
9
|
+
* Отдаёт его пакет адаптера — он единственный, кто знает и то, и другое. Команды сборки
|
|
10
|
+
* пресет не разбирают, а укладывают: `plugins` — в конфиг сборщика, `clientEntry` — в
|
|
11
|
+
* сгенерированный клиентский вход.
|
|
12
|
+
*/
|
|
13
|
+
interface AppBuildPreset {
|
|
14
|
+
/** Имя фреймворка — им пресет представляется в логах и сообщениях об ошибках. */
|
|
15
|
+
view: string;
|
|
16
|
+
/** Плагины сборщика, которыми рисуется этот фреймворк. */
|
|
17
|
+
plugins: PluginOption[];
|
|
18
|
+
/**
|
|
19
|
+
* Модуль с `hydrateApp(descriptor)` — по нему сборка генерирует клиентский вход.
|
|
20
|
+
*
|
|
21
|
+
* Специфицируется именем, а не функцией: вход собирается в браузерный бандл, и функция из
|
|
22
|
+
* процесса сборки в него не переедет.
|
|
23
|
+
*/
|
|
24
|
+
clientEntry: string;
|
|
25
|
+
/**
|
|
26
|
+
* Проверка, что пресету хватает объявленного: получает зависимости приложения, возвращает
|
|
27
|
+
* причину отказа либо `null`.
|
|
28
|
+
*
|
|
29
|
+
* Здесь, а не в командах: какая зависимость требует сборочной поддержки, знает пресет —
|
|
30
|
+
* командам об этом знать нечем, и захардкоженный список сделал бы их привязанными к стеку.
|
|
31
|
+
* Нужна проверка потому, что цена ошибки — молчание: имена классов разъезжаются между
|
|
32
|
+
* выходами, и это видно только сломанной гидрацией в браузере.
|
|
33
|
+
*/
|
|
34
|
+
validate?: (dependencies: string[]) => string | null;
|
|
35
|
+
}
|
|
36
|
+
/** Серверная часть конфига — всё, что вплавляется в серверный выход. */
|
|
37
|
+
interface AppServerConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Настройка процесса перед первым рендером: разбор разметки, полифиллы, прогрев.
|
|
40
|
+
*
|
|
41
|
+
* Дожидается её движок, один раз на процесс, — приложению ждать не нужно.
|
|
42
|
+
*/
|
|
43
|
+
setup?: () => void | Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Обёртка серверного рендера: через неё собираются стили, которые фреймворк заводит по
|
|
46
|
+
* ходу рендера, и уезжают в `<head>` разметкой.
|
|
47
|
+
*/
|
|
48
|
+
render?: ServerRender;
|
|
49
|
+
/**
|
|
50
|
+
* Биндинги app-контейнера: адрес ручек, ключи, всё, что приложение читает через `requires`.
|
|
51
|
+
*
|
|
52
|
+
* Контейнер приложения — родитель контейнеров островов, поэтому положенное здесь резолвится
|
|
53
|
+
* по parent-chain на любом рендере.
|
|
54
|
+
*/
|
|
55
|
+
container?: (container: Container) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Расширение сетевого инстанса до начала прослушивания: Sentry, метрики, cors.
|
|
58
|
+
*
|
|
59
|
+
* Зовётся только сетевым транспортом — в процессе хоста инстанса нет.
|
|
60
|
+
*/
|
|
61
|
+
configure?: (instance: FastifyInstance) => void | Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Зависимости, которые серверный выход обязан собрать ИСХОДНИКАМИ, а не оставить внешним
|
|
64
|
+
* модулем.
|
|
65
|
+
*
|
|
66
|
+
* Нужно тем пакетам, чей выход не переживает загрузку через node-ESM: интероп
|
|
67
|
+
* default-экспорта разъезжается, и вместо фабрики приходит пространство имён модуля.
|
|
68
|
+
*/
|
|
69
|
+
noExternal?: Array<string | RegExp>;
|
|
70
|
+
}
|
|
71
|
+
/** Конфиг приложения. */
|
|
72
|
+
interface AppConfig {
|
|
73
|
+
/** Модуль дескриптора; по умолчанию `src/index.ts`. */
|
|
74
|
+
entry?: string;
|
|
75
|
+
/** Пресет фреймворка — из пакета адаптера. */
|
|
76
|
+
preset: AppBuildPreset;
|
|
77
|
+
server?: AppServerConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Последнее слово за приложением: правит собранный конфиг сборщика перед запуском.
|
|
80
|
+
*
|
|
81
|
+
* Щель на случай, когда коробки не хватило. Зовётся отдельно для каждого выхода, поэтому
|
|
82
|
+
* правка адресуется тому, кому предназначена.
|
|
83
|
+
*/
|
|
84
|
+
vite?: (config: Record<string, unknown>, target: 'server' | 'client') => Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Объявляет конфиг приложения.
|
|
88
|
+
*
|
|
89
|
+
* Функция, а не голый объект, ради типизации на месте: интерфейс проверяется там, где конфиг
|
|
90
|
+
* написан, а не там, где его прочитали команды.
|
|
91
|
+
*
|
|
92
|
+
* @param config - Конфиг приложения
|
|
93
|
+
*/
|
|
94
|
+
declare function defineAppConfig(config: AppConfig): AppConfig;
|
|
95
|
+
|
|
96
|
+
/** Режим сборки: им плагины выбирают рантайм фреймворка. */
|
|
97
|
+
type BuildMode = 'production' | 'development';
|
|
98
|
+
/** Что нужно собрать. */
|
|
99
|
+
interface BuildAppOptions {
|
|
100
|
+
/** Корень приложения. */
|
|
101
|
+
root: string;
|
|
102
|
+
/** Префикс адресов артефактов: в проде CDN, в разработке развязка у хоста. */
|
|
103
|
+
base?: string;
|
|
104
|
+
/** Режим сборки; по умолчанию `production`. */
|
|
105
|
+
mode?: BuildMode;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Собирает приложение целиком.
|
|
109
|
+
*
|
|
110
|
+
* @param options - Корень приложения и префикс адресов артефактов
|
|
111
|
+
* @throws Если конфига нет либо пресет сообщил, что ему не хватает объявленного
|
|
112
|
+
*/
|
|
113
|
+
declare function buildApp(options: BuildAppOptions): Promise<void>;
|
|
114
|
+
|
|
115
|
+
/** Наблюдение берёт те же опции, что сборка: путь у них один. */
|
|
116
|
+
type DevAppOptions = BuildAppOptions;
|
|
117
|
+
/**
|
|
118
|
+
* Собирает приложение и держит его поднятым, пересобирая на изменение исходников.
|
|
119
|
+
*
|
|
120
|
+
* @param options - Корень приложения и префикс адресов артефактов
|
|
121
|
+
*/
|
|
122
|
+
declare function devApp(options: DevAppOptions): Promise<void>;
|
|
123
|
+
|
|
124
|
+
export { type AppBuildPreset, type AppConfig, type AppServerConfig, type BuildAppOptions, type DevAppOptions, buildApp, defineAppConfig, devApp };
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { a as ServerRender } from '../server-render-CocWXQKC.js';
|
|
2
|
+
import { Container } from '@foxford/ioc';
|
|
3
|
+
import { FastifyInstance } from 'fastify';
|
|
4
|
+
import { PluginOption } from 'vite';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Пресет фреймворка: чем собирать его исходники и чем оживлять фрагмент в браузере.
|
|
8
|
+
*
|
|
9
|
+
* Отдаёт его пакет адаптера — он единственный, кто знает и то, и другое. Команды сборки
|
|
10
|
+
* пресет не разбирают, а укладывают: `plugins` — в конфиг сборщика, `clientEntry` — в
|
|
11
|
+
* сгенерированный клиентский вход.
|
|
12
|
+
*/
|
|
13
|
+
interface AppBuildPreset {
|
|
14
|
+
/** Имя фреймворка — им пресет представляется в логах и сообщениях об ошибках. */
|
|
15
|
+
view: string;
|
|
16
|
+
/** Плагины сборщика, которыми рисуется этот фреймворк. */
|
|
17
|
+
plugins: PluginOption[];
|
|
18
|
+
/**
|
|
19
|
+
* Модуль с `hydrateApp(descriptor)` — по нему сборка генерирует клиентский вход.
|
|
20
|
+
*
|
|
21
|
+
* Специфицируется именем, а не функцией: вход собирается в браузерный бандл, и функция из
|
|
22
|
+
* процесса сборки в него не переедет.
|
|
23
|
+
*/
|
|
24
|
+
clientEntry: string;
|
|
25
|
+
/**
|
|
26
|
+
* Проверка, что пресету хватает объявленного: получает зависимости приложения, возвращает
|
|
27
|
+
* причину отказа либо `null`.
|
|
28
|
+
*
|
|
29
|
+
* Здесь, а не в командах: какая зависимость требует сборочной поддержки, знает пресет —
|
|
30
|
+
* командам об этом знать нечем, и захардкоженный список сделал бы их привязанными к стеку.
|
|
31
|
+
* Нужна проверка потому, что цена ошибки — молчание: имена классов разъезжаются между
|
|
32
|
+
* выходами, и это видно только сломанной гидрацией в браузере.
|
|
33
|
+
*/
|
|
34
|
+
validate?: (dependencies: string[]) => string | null;
|
|
35
|
+
}
|
|
36
|
+
/** Серверная часть конфига — всё, что вплавляется в серверный выход. */
|
|
37
|
+
interface AppServerConfig {
|
|
38
|
+
/**
|
|
39
|
+
* Настройка процесса перед первым рендером: разбор разметки, полифиллы, прогрев.
|
|
40
|
+
*
|
|
41
|
+
* Дожидается её движок, один раз на процесс, — приложению ждать не нужно.
|
|
42
|
+
*/
|
|
43
|
+
setup?: () => void | Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Обёртка серверного рендера: через неё собираются стили, которые фреймворк заводит по
|
|
46
|
+
* ходу рендера, и уезжают в `<head>` разметкой.
|
|
47
|
+
*/
|
|
48
|
+
render?: ServerRender;
|
|
49
|
+
/**
|
|
50
|
+
* Биндинги app-контейнера: адрес ручек, ключи, всё, что приложение читает через `requires`.
|
|
51
|
+
*
|
|
52
|
+
* Контейнер приложения — родитель контейнеров островов, поэтому положенное здесь резолвится
|
|
53
|
+
* по parent-chain на любом рендере.
|
|
54
|
+
*/
|
|
55
|
+
container?: (container: Container) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Расширение сетевого инстанса до начала прослушивания: Sentry, метрики, cors.
|
|
58
|
+
*
|
|
59
|
+
* Зовётся только сетевым транспортом — в процессе хоста инстанса нет.
|
|
60
|
+
*/
|
|
61
|
+
configure?: (instance: FastifyInstance) => void | Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Зависимости, которые серверный выход обязан собрать ИСХОДНИКАМИ, а не оставить внешним
|
|
64
|
+
* модулем.
|
|
65
|
+
*
|
|
66
|
+
* Нужно тем пакетам, чей выход не переживает загрузку через node-ESM: интероп
|
|
67
|
+
* default-экспорта разъезжается, и вместо фабрики приходит пространство имён модуля.
|
|
68
|
+
*/
|
|
69
|
+
noExternal?: Array<string | RegExp>;
|
|
70
|
+
}
|
|
71
|
+
/** Конфиг приложения. */
|
|
72
|
+
interface AppConfig {
|
|
73
|
+
/** Модуль дескриптора; по умолчанию `src/index.ts`. */
|
|
74
|
+
entry?: string;
|
|
75
|
+
/** Пресет фреймворка — из пакета адаптера. */
|
|
76
|
+
preset: AppBuildPreset;
|
|
77
|
+
server?: AppServerConfig;
|
|
78
|
+
/**
|
|
79
|
+
* Последнее слово за приложением: правит собранный конфиг сборщика перед запуском.
|
|
80
|
+
*
|
|
81
|
+
* Щель на случай, когда коробки не хватило. Зовётся отдельно для каждого выхода, поэтому
|
|
82
|
+
* правка адресуется тому, кому предназначена.
|
|
83
|
+
*/
|
|
84
|
+
vite?: (config: Record<string, unknown>, target: 'server' | 'client') => Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Объявляет конфиг приложения.
|
|
88
|
+
*
|
|
89
|
+
* Функция, а не голый объект, ради типизации на месте: интерфейс проверяется там, где конфиг
|
|
90
|
+
* написан, а не там, где его прочитали команды.
|
|
91
|
+
*
|
|
92
|
+
* @param config - Конфиг приложения
|
|
93
|
+
*/
|
|
94
|
+
declare function defineAppConfig(config: AppConfig): AppConfig;
|
|
95
|
+
|
|
96
|
+
/** Режим сборки: им плагины выбирают рантайм фреймворка. */
|
|
97
|
+
type BuildMode = 'production' | 'development';
|
|
98
|
+
/** Что нужно собрать. */
|
|
99
|
+
interface BuildAppOptions {
|
|
100
|
+
/** Корень приложения. */
|
|
101
|
+
root: string;
|
|
102
|
+
/** Префикс адресов артефактов: в проде CDN, в разработке развязка у хоста. */
|
|
103
|
+
base?: string;
|
|
104
|
+
/** Режим сборки; по умолчанию `production`. */
|
|
105
|
+
mode?: BuildMode;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Собирает приложение целиком.
|
|
109
|
+
*
|
|
110
|
+
* @param options - Корень приложения и префикс адресов артефактов
|
|
111
|
+
* @throws Если конфига нет либо пресет сообщил, что ему не хватает объявленного
|
|
112
|
+
*/
|
|
113
|
+
declare function buildApp(options: BuildAppOptions): Promise<void>;
|
|
114
|
+
|
|
115
|
+
/** Наблюдение берёт те же опции, что сборка: путь у них один. */
|
|
116
|
+
type DevAppOptions = BuildAppOptions;
|
|
117
|
+
/**
|
|
118
|
+
* Собирает приложение и держит его поднятым, пересобирая на изменение исходников.
|
|
119
|
+
*
|
|
120
|
+
* @param options - Корень приложения и префикс адресов артефактов
|
|
121
|
+
*/
|
|
122
|
+
declare function devApp(options: DevAppOptions): Promise<void>;
|
|
123
|
+
|
|
124
|
+
export { type AppBuildPreset, type AppConfig, type AppServerConfig, type BuildAppOptions, type DevAppOptions, buildApp, defineAppConfig, devApp };
|