@eighty4/dank 0.0.4-2 → 0.0.4
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/client/client.js +1 -0
- package/lib/bin.ts +8 -11
- package/lib/build.ts +43 -70
- package/lib/build_tag.ts +3 -3
- package/lib/config.ts +184 -29
- package/lib/dank.ts +7 -0
- package/lib/define.ts +6 -4
- package/lib/developer.ts +33 -4
- package/lib/dirs.ts +83 -0
- package/lib/errors.ts +6 -0
- package/lib/esbuild.ts +19 -29
- package/lib/flags.ts +16 -122
- package/lib/html.ts +196 -112
- package/lib/http.ts +59 -43
- package/lib/public.ts +10 -10
- package/lib/{metadata.ts → registry.ts} +216 -83
- package/lib/serve.ts +101 -336
- package/lib/services.ts +8 -8
- package/lib/watch.ts +39 -0
- package/lib_js/bin.js +8 -10
- package/lib_js/build.js +31 -45
- package/lib_js/build_tag.js +2 -2
- package/lib_js/config.js +108 -29
- package/lib_js/define.js +3 -3
- package/lib_js/dirs.js +61 -0
- package/lib_js/errors.js +9 -0
- package/lib_js/esbuild.js +17 -19
- package/lib_js/flags.js +9 -98
- package/lib_js/html.js +127 -64
- package/lib_js/http.js +18 -18
- package/lib_js/public.js +9 -9
- package/lib_js/{metadata.js → registry.js} +121 -51
- package/lib_js/serve.js +53 -177
- package/lib_js/services.js +6 -6
- package/lib_js/watch.js +35 -0
- package/lib_types/dank.d.ts +5 -0
- package/package.json +6 -4
- package/client/esbuild.js +0 -1
package/lib_js/build.js
CHANGED
|
@@ -1,71 +1,57 @@
|
|
|
1
1
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { createBuildTag } from "./build_tag.js";
|
|
4
|
+
import { loadConfig } from "./config.js";
|
|
4
5
|
import { createGlobalDefinitions } from "./define.js";
|
|
5
6
|
import { esbuildWebpages, esbuildWorkers } from "./esbuild.js";
|
|
6
|
-
import { resolveBuildFlags } from "./flags.js";
|
|
7
|
-
import { HtmlEntrypoint } from "./html.js";
|
|
8
|
-
import { WebsiteRegistry } from "./metadata.js";
|
|
9
7
|
import { copyAssets } from "./public.js";
|
|
8
|
+
import { WebsiteRegistry } from "./registry.js";
|
|
10
9
|
async function buildWebsite(c) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
await
|
|
15
|
-
|
|
10
|
+
if (!c) {
|
|
11
|
+
c = await loadConfig("build", process.cwd());
|
|
12
|
+
}
|
|
13
|
+
const buildTag = await createBuildTag(c.flags);
|
|
14
|
+
console.log(c.flags.minify ? c.flags.production ? "minified production" : "minified" : "unminified", "build", buildTag, "building in ./build/dist");
|
|
15
|
+
await rm(c.dirs.buildRoot, { recursive: true, force: true });
|
|
16
|
+
await mkdir(c.dirs.buildDist, { recursive: true });
|
|
16
17
|
for (const subdir of Object.keys(c.pages).filter((url) => url !== "/")) {
|
|
17
|
-
await mkdir(join(
|
|
18
|
+
await mkdir(join(c.dirs.buildDist, subdir), { recursive: true });
|
|
18
19
|
}
|
|
19
|
-
await mkdir(join(
|
|
20
|
-
const registry =
|
|
21
|
-
registry.pageUrls = Object.keys(c.pages);
|
|
22
|
-
registry.copiedAssets = await copyAssets(build);
|
|
23
|
-
await buildWebpages(c, registry, build, createGlobalDefinitions(build));
|
|
20
|
+
await mkdir(join(c.dirs.buildRoot, "metafiles"), { recursive: true });
|
|
21
|
+
const registry = await buildWebpages(c, createGlobalDefinitions(c));
|
|
24
22
|
return await registry.writeManifest(buildTag);
|
|
25
23
|
}
|
|
26
|
-
async function buildWebpages(c,
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
htmlEntrypoints.push(html);
|
|
34
|
-
}
|
|
35
|
-
const uniqueEntryPoints = /* @__PURE__ */ new Set();
|
|
36
|
-
const buildEntryPoints = [];
|
|
37
|
-
for (const pageEntryPoints of await Promise.all(loadingEntryPoints)) {
|
|
38
|
-
for (const entryPoint of pageEntryPoints) {
|
|
39
|
-
if (!uniqueEntryPoints.has(entryPoint.in)) {
|
|
40
|
-
buildEntryPoints.push(entryPoint);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
await esbuildWebpages(build, registry, define, buildEntryPoints, c.esbuild);
|
|
45
|
-
const workerEntryPoints = registry.workerEntryPoints();
|
|
24
|
+
async function buildWebpages(c, define) {
|
|
25
|
+
const registry = new WebsiteRegistry(c);
|
|
26
|
+
registry.configSync();
|
|
27
|
+
registry.copiedAssets = await copyAssets(c.dirs);
|
|
28
|
+
await Promise.all(registry.htmlEntrypoints.map((html) => html.process()));
|
|
29
|
+
await esbuildWebpages(registry, define, registry.webpageEntryPoints);
|
|
30
|
+
const workerEntryPoints = registry.workerEntryPoints;
|
|
46
31
|
if (workerEntryPoints?.length) {
|
|
47
|
-
await esbuildWorkers(
|
|
32
|
+
await esbuildWorkers(registry, define, workerEntryPoints);
|
|
48
33
|
}
|
|
49
|
-
await rewriteWorkerUrls(
|
|
50
|
-
await Promise.all(htmlEntrypoints.map(async (html) => {
|
|
51
|
-
await writeFile(join(
|
|
34
|
+
await rewriteWorkerUrls(c.dirs, registry);
|
|
35
|
+
await Promise.all(registry.htmlEntrypoints.map(async (html) => {
|
|
36
|
+
await writeFile(join(c.dirs.buildDist, html.url, "index.html"), html.output(registry));
|
|
52
37
|
}));
|
|
38
|
+
return registry;
|
|
53
39
|
}
|
|
54
|
-
async function rewriteWorkerUrls(
|
|
55
|
-
const workers = registry.workers
|
|
40
|
+
async function rewriteWorkerUrls(dirs, registry) {
|
|
41
|
+
const workers = registry.workers;
|
|
56
42
|
if (!workers) {
|
|
57
43
|
return;
|
|
58
44
|
}
|
|
59
45
|
const dependentBundlePaths = workers.map((w) => registry.mappedHref(w.dependentEntryPoint));
|
|
60
46
|
const bundleOutputs = {};
|
|
61
47
|
const readingFiles = Promise.all(dependentBundlePaths.map(async (p) => {
|
|
62
|
-
bundleOutputs[p] = await readFile(join(
|
|
48
|
+
bundleOutputs[p] = await readFile(join(dirs.projectRootAbs, dirs.buildDist, p), "utf8");
|
|
63
49
|
}));
|
|
64
50
|
const rewriteChains = {};
|
|
65
51
|
for (const p of dependentBundlePaths)
|
|
66
52
|
rewriteChains[p] = [];
|
|
67
53
|
for (const w of workers) {
|
|
68
|
-
rewriteChains[registry.mappedHref(w.dependentEntryPoint)].push((s) => s.replace(createWorkerRegex(w.workerUrlPlaceholder), `new
|
|
54
|
+
rewriteChains[registry.mappedHref(w.dependentEntryPoint)].push((s) => s.replace(createWorkerRegex(w.workerCtor, w.workerUrlPlaceholder), `new ${w.workerCtor}('${registry.mappedHref(w.workerEntryPoint)}')`));
|
|
69
55
|
}
|
|
70
56
|
await readingFiles;
|
|
71
57
|
await Promise.all(Object.entries(bundleOutputs).map(async ([p, content]) => {
|
|
@@ -73,11 +59,11 @@ async function rewriteWorkerUrls(build, registry) {
|
|
|
73
59
|
for (const rewriteFn of rewriteChains[p]) {
|
|
74
60
|
result = rewriteFn(result);
|
|
75
61
|
}
|
|
76
|
-
await writeFile(join(
|
|
62
|
+
await writeFile(join(dirs.projectRootAbs, dirs.buildDist, p), result);
|
|
77
63
|
}));
|
|
78
64
|
}
|
|
79
|
-
function createWorkerRegex(workerUrl) {
|
|
80
|
-
return new RegExp(`new(?:\\s|\\r?\\n)
|
|
65
|
+
function createWorkerRegex(workerCtor, workerUrl) {
|
|
66
|
+
return new RegExp(`new(?:\\s|\\r?\\n)+${workerCtor}(?:\\s|\\r?\\n)*\\((?:\\s|\\r?\\n)*['"]${workerUrl}['"](?:\\s|\\r?\\n)*\\)`, "g");
|
|
81
67
|
}
|
|
82
68
|
export {
|
|
83
69
|
buildWebsite,
|
package/lib_js/build_tag.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { exec } from "node:child_process";
|
|
2
|
-
async function createBuildTag(
|
|
2
|
+
async function createBuildTag(flags) {
|
|
3
3
|
const now = /* @__PURE__ */ new Date();
|
|
4
4
|
const ms = now.getUTCMilliseconds() + now.getUTCSeconds() * 1e3 + now.getUTCMinutes() * 1e3 * 60 + now.getUTCHours() * 1e3 * 60 * 60;
|
|
5
5
|
const date = now.toISOString().substring(0, 10);
|
|
6
6
|
const time = String(ms).padStart(8, "0");
|
|
7
7
|
const when = `${date}-${time}`;
|
|
8
|
-
if (
|
|
8
|
+
if (flags.production) {
|
|
9
9
|
const gitHash = await new Promise((res, rej) => exec("git rev-parse --short HEAD", (err, stdout) => {
|
|
10
10
|
if (err)
|
|
11
11
|
rej(err);
|
package/lib_js/config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isAbsolute, resolve } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { defaultProjectDirs } from "./dirs.js";
|
|
3
|
+
import { resolveFlags as lookupDankFlags } from "./flags.js";
|
|
3
4
|
var __rewriteRelativeImportExtension = function(path, preserveJsx) {
|
|
4
5
|
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
5
6
|
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function(m, tsx, d, ext, cm) {
|
|
@@ -8,31 +9,90 @@ var __rewriteRelativeImportExtension = function(path, preserveJsx) {
|
|
|
8
9
|
}
|
|
9
10
|
return path;
|
|
10
11
|
};
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const DEFAULT_DEV_PORT = 3e3;
|
|
13
|
+
const DEFAULT_PREVIEW_PORT = 4e3;
|
|
14
|
+
const DEFAULT_ESBUILD_PORT = 3995;
|
|
15
|
+
const DEFAULT_CONFIG_PATH = "./dank.config.ts";
|
|
16
|
+
async function loadConfig(mode, projectRootAbs) {
|
|
17
|
+
if (!isAbsolute(projectRootAbs)) {
|
|
18
|
+
throw Error();
|
|
19
|
+
}
|
|
20
|
+
const modulePath = resolve(projectRootAbs, DEFAULT_CONFIG_PATH);
|
|
21
|
+
const dirs = await defaultProjectDirs(projectRootAbs);
|
|
22
|
+
const c = new DankConfigInternal(mode, modulePath, dirs);
|
|
23
|
+
await c.reload();
|
|
16
24
|
return c;
|
|
17
25
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
class DankConfigInternal {
|
|
27
|
+
#dirs;
|
|
28
|
+
#flags;
|
|
29
|
+
#mode;
|
|
30
|
+
#modulePath;
|
|
31
|
+
#dankPort = DEFAULT_DEV_PORT;
|
|
32
|
+
#esbuildPort = DEFAULT_ESBUILD_PORT;
|
|
33
|
+
#esbuild;
|
|
34
|
+
#pages = {};
|
|
35
|
+
#devPages;
|
|
36
|
+
#services;
|
|
37
|
+
constructor(mode, modulePath, dirs) {
|
|
38
|
+
this.#dirs = dirs;
|
|
39
|
+
this.#flags = lookupDankFlags();
|
|
40
|
+
this.#mode = mode;
|
|
41
|
+
this.#modulePath = modulePath;
|
|
42
|
+
}
|
|
43
|
+
get dankPort() {
|
|
44
|
+
return this.#dankPort;
|
|
45
|
+
}
|
|
46
|
+
get esbuildPort() {
|
|
47
|
+
return this.#esbuildPort;
|
|
48
|
+
}
|
|
49
|
+
get esbuild() {
|
|
50
|
+
return this.#esbuild;
|
|
51
|
+
}
|
|
52
|
+
get dirs() {
|
|
53
|
+
return this.#dirs;
|
|
54
|
+
}
|
|
55
|
+
get flags() {
|
|
56
|
+
return this.#flags;
|
|
57
|
+
}
|
|
58
|
+
get mode() {
|
|
59
|
+
return this.#mode;
|
|
60
|
+
}
|
|
61
|
+
get pages() {
|
|
62
|
+
return this.#pages;
|
|
63
|
+
}
|
|
64
|
+
get devPages() {
|
|
65
|
+
return this.#devPages;
|
|
66
|
+
}
|
|
67
|
+
get services() {
|
|
68
|
+
return this.#services;
|
|
69
|
+
}
|
|
70
|
+
async reload() {
|
|
71
|
+
const userConfig = await resolveConfig(this.#modulePath, resolveDankDetails(this.#mode, this.#flags));
|
|
72
|
+
this.#dankPort = resolveDankPort(this.#flags, userConfig);
|
|
73
|
+
this.#esbuildPort = resolveEsbuildPort(this.#flags, userConfig);
|
|
74
|
+
this.#esbuild = Object.freeze(userConfig.esbuild);
|
|
75
|
+
this.#pages = Object.freeze(normalizePages(userConfig.pages));
|
|
76
|
+
this.#devPages = Object.freeze(userConfig.devPages);
|
|
77
|
+
this.#services = Object.freeze(userConfig.services);
|
|
23
78
|
}
|
|
24
79
|
}
|
|
25
|
-
|
|
80
|
+
function resolveDankPort(flags, userConfig) {
|
|
81
|
+
return flags.dankPort || (flags.preview ? userConfig.previewPort || userConfig.port || DEFAULT_PREVIEW_PORT : userConfig.port || DEFAULT_DEV_PORT);
|
|
82
|
+
}
|
|
83
|
+
function resolveEsbuildPort(flags, userConfig) {
|
|
84
|
+
return flags.esbuildPort || userConfig.esbuild?.port || DEFAULT_ESBUILD_PORT;
|
|
85
|
+
}
|
|
86
|
+
async function resolveConfig(modulePath, details) {
|
|
26
87
|
const module = await import(__rewriteRelativeImportExtension(`${modulePath}?${Date.now()}`));
|
|
27
|
-
const c = typeof module.default === "function" ? await module.default(
|
|
88
|
+
const c = typeof module.default === "function" ? await module.default(details) : module.default;
|
|
28
89
|
validateDankConfig(c);
|
|
29
90
|
return c;
|
|
30
91
|
}
|
|
31
|
-
function resolveDankDetails(mode) {
|
|
32
|
-
const production = isProductionBuild();
|
|
92
|
+
function resolveDankDetails(mode, flags) {
|
|
33
93
|
return {
|
|
34
|
-
dev: !production,
|
|
35
|
-
production,
|
|
94
|
+
dev: !flags.production,
|
|
95
|
+
production: flags.production,
|
|
36
96
|
mode
|
|
37
97
|
};
|
|
38
98
|
}
|
|
@@ -40,6 +100,7 @@ function validateDankConfig(c) {
|
|
|
40
100
|
try {
|
|
41
101
|
validatePorts(c);
|
|
42
102
|
validatePages(c.pages);
|
|
103
|
+
validateDevPages(c.devPages);
|
|
43
104
|
validateDevServices(c.services);
|
|
44
105
|
validateEsbuildConfig(c.esbuild);
|
|
45
106
|
} catch (e) {
|
|
@@ -96,6 +157,29 @@ function validatePages(pages) {
|
|
|
96
157
|
throw Error(`DankConfig.pages['${urlPath}'] must configure an html file`);
|
|
97
158
|
}
|
|
98
159
|
}
|
|
160
|
+
function validateDevPages(devPages) {
|
|
161
|
+
if (devPages) {
|
|
162
|
+
for (const [urlPath, mapping] of Object.entries(devPages)) {
|
|
163
|
+
if (!urlPath.startsWith("/__")) {
|
|
164
|
+
throw Error(`DankConfig.devPages['${urlPath}'] must start \`${urlPath}\` with a \`/__\` path prefix`);
|
|
165
|
+
}
|
|
166
|
+
if (typeof mapping === "string") {
|
|
167
|
+
if (!mapping.endsWith(".html")) {
|
|
168
|
+
throw Error(`DankConfig.devPages['${urlPath}'] must configure an html file or DevPageMapping config`);
|
|
169
|
+
}
|
|
170
|
+
} else if (typeof mapping === "object") {
|
|
171
|
+
if (typeof mapping.label !== "string" || !mapping.label.length) {
|
|
172
|
+
throw Error(`DankConfig.devPages['${urlPath}'].label must declare a label`);
|
|
173
|
+
}
|
|
174
|
+
if (typeof mapping.webpage !== "string" || !mapping.webpage.endsWith(".html")) {
|
|
175
|
+
throw Error(`DankConfig.devPages['${urlPath}'].webpage must configure an html file`);
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
throw Error(`DankConfig.devPages['${urlPath}'] must be a DevPageMapping config with \`label\` and \`webpage\` values`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
99
183
|
function validatePageMapping(urlPath, mapping) {
|
|
100
184
|
if (mapping.webpage === null || typeof mapping.webpage !== "string" || !mapping.webpage.endsWith(".html")) {
|
|
101
185
|
throw Error(`DankConfig.pages['${urlPath}'].webpage must configure an html file`);
|
|
@@ -144,20 +228,15 @@ function validateDevServices(services) {
|
|
|
144
228
|
}
|
|
145
229
|
}
|
|
146
230
|
}
|
|
147
|
-
function
|
|
231
|
+
function normalizePages(pages) {
|
|
232
|
+
const result = {};
|
|
148
233
|
for (const [pageUrl, mapping] of Object.entries(pages)) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
mapping.webpage = normalizePagePath(mapping.webpage);
|
|
153
|
-
}
|
|
234
|
+
const mappedMapping = typeof mapping === "string" ? { webpage: mapping } : mapping;
|
|
235
|
+
mappedMapping.webpage = mappedMapping.webpage.replace(/^\.\//, "");
|
|
236
|
+
result[pageUrl] = mappedMapping;
|
|
154
237
|
}
|
|
155
|
-
|
|
156
|
-
function normalizePagePath(p) {
|
|
157
|
-
return p.replace(/^\.\//, "");
|
|
238
|
+
return result;
|
|
158
239
|
}
|
|
159
240
|
export {
|
|
160
|
-
loadConfig
|
|
161
|
-
resolveConfig,
|
|
162
|
-
resolveConfigPath
|
|
241
|
+
loadConfig
|
|
163
242
|
};
|
package/lib_js/define.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
function createGlobalDefinitions(
|
|
1
|
+
function createGlobalDefinitions(c) {
|
|
2
2
|
return {
|
|
3
|
-
"dank.IS_DEV": JSON.stringify(!
|
|
4
|
-
"dank.IS_PROD": JSON.stringify(
|
|
3
|
+
"dank.IS_DEV": JSON.stringify(!c.flags.production),
|
|
4
|
+
"dank.IS_PROD": JSON.stringify(c.flags.production)
|
|
5
5
|
};
|
|
6
6
|
}
|
|
7
7
|
export {
|
package/lib_js/dirs.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { realpath } from "node:fs/promises";
|
|
2
|
+
import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
import { cwd } from "node:process";
|
|
4
|
+
async function defaultProjectDirs(projectRootAbs) {
|
|
5
|
+
if (!projectRootAbs) {
|
|
6
|
+
projectRootAbs = cwd();
|
|
7
|
+
} else if (!isAbsolute(projectRootAbs)) {
|
|
8
|
+
throw Error();
|
|
9
|
+
}
|
|
10
|
+
const projectResolved = await realpath(projectRootAbs);
|
|
11
|
+
const pages = "pages";
|
|
12
|
+
const pagesResolved = join(projectResolved, pages);
|
|
13
|
+
return Object.freeze({
|
|
14
|
+
buildRoot: "build",
|
|
15
|
+
buildDist: join("build", "dist"),
|
|
16
|
+
buildWatch: join("build", "watch"),
|
|
17
|
+
pages,
|
|
18
|
+
pagesResolved,
|
|
19
|
+
projectResolved,
|
|
20
|
+
projectRootAbs,
|
|
21
|
+
public: "public"
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
class Resolver {
|
|
25
|
+
#dirs;
|
|
26
|
+
constructor(dirs) {
|
|
27
|
+
this.#dirs = dirs;
|
|
28
|
+
}
|
|
29
|
+
// cross platform safe absolute path resolution from pages dir
|
|
30
|
+
absPagesPath(...p) {
|
|
31
|
+
return join(this.#dirs.projectRootAbs, this.#dirs.pages, ...p);
|
|
32
|
+
}
|
|
33
|
+
// cross platform safe absolute path resolution from project root
|
|
34
|
+
absProjectPath(...p) {
|
|
35
|
+
return join(this.#dirs.projectRootAbs, ...p);
|
|
36
|
+
}
|
|
37
|
+
// `p` is expected to be a relative path resolvable from the project dir
|
|
38
|
+
isProjectSubpathInPagesDir(p) {
|
|
39
|
+
return resolve(join(this.#dirs.projectResolved, p)).startsWith(this.#dirs.pagesResolved);
|
|
40
|
+
}
|
|
41
|
+
// `p` is expected to be a relative path resolvable from the pages dir
|
|
42
|
+
isPagesSubpathInPagesDir(p) {
|
|
43
|
+
return this.isProjectSubpathInPagesDir(join(this.#dirs.pages, p));
|
|
44
|
+
}
|
|
45
|
+
// resolve a pages subpath from a resource within the pages directory by a relative href
|
|
46
|
+
// `from` is expected to be a pages resource fs path starting with `pages/` and ending with filename
|
|
47
|
+
// the result will be a pages subpath and will not have the pages dir prefix
|
|
48
|
+
// returns 'outofbounds' if the relative path does not resolve to a file within the pages dir
|
|
49
|
+
resolveHrefInPagesDir(from, href) {
|
|
50
|
+
const p = join(dirname(from), href);
|
|
51
|
+
if (this.isProjectSubpathInPagesDir(p)) {
|
|
52
|
+
return p;
|
|
53
|
+
} else {
|
|
54
|
+
return "outofbounds";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
Resolver,
|
|
60
|
+
defaultProjectDirs
|
|
61
|
+
};
|
package/lib_js/errors.js
ADDED
package/lib_js/esbuild.js
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import esbuild, {} from "esbuild";
|
|
3
|
-
async function esbuildDevContext(
|
|
3
|
+
async function esbuildDevContext(r, define, entryPoints) {
|
|
4
4
|
return await esbuild.context({
|
|
5
5
|
define,
|
|
6
6
|
entryNames: "[dir]/[name]",
|
|
7
7
|
entryPoints: mapEntryPointPaths(entryPoints),
|
|
8
|
-
outdir:
|
|
9
|
-
...commonBuildOptions(
|
|
8
|
+
outdir: r.config.dirs.buildWatch,
|
|
9
|
+
...commonBuildOptions(r),
|
|
10
10
|
splitting: false,
|
|
11
11
|
write: false
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
|
-
async function esbuildWebpages(
|
|
14
|
+
async function esbuildWebpages(r, define, entryPoints) {
|
|
15
15
|
try {
|
|
16
16
|
await esbuild.build({
|
|
17
17
|
define,
|
|
18
18
|
entryNames: "[dir]/[name]-[hash]",
|
|
19
19
|
entryPoints: mapEntryPointPaths(entryPoints),
|
|
20
|
-
outdir:
|
|
21
|
-
...commonBuildOptions(
|
|
20
|
+
outdir: r.config.dirs.buildDist,
|
|
21
|
+
...commonBuildOptions(r)
|
|
22
22
|
});
|
|
23
23
|
} catch (ignore) {
|
|
24
24
|
process.exit(1);
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
|
-
async function esbuildWorkers(
|
|
27
|
+
async function esbuildWorkers(r, define, entryPoints) {
|
|
28
28
|
try {
|
|
29
29
|
await esbuild.build({
|
|
30
30
|
define,
|
|
31
31
|
entryNames: "[dir]/[name]-[hash]",
|
|
32
32
|
entryPoints: mapEntryPointPaths(entryPoints),
|
|
33
|
-
outdir:
|
|
34
|
-
...commonBuildOptions(
|
|
33
|
+
outdir: r.config.dirs.buildDist,
|
|
34
|
+
...commonBuildOptions(r),
|
|
35
35
|
splitting: false,
|
|
36
36
|
metafile: true,
|
|
37
37
|
write: true,
|
|
@@ -41,18 +41,17 @@ async function esbuildWorkers(b, r, define, entryPoints, c) {
|
|
|
41
41
|
process.exit(1);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
function commonBuildOptions(
|
|
44
|
+
function commonBuildOptions(r) {
|
|
45
45
|
const p = workersPlugin(r.buildRegistry());
|
|
46
46
|
return {
|
|
47
|
-
absWorkingDir: b.dirs.projectRootAbs,
|
|
48
47
|
assetNames: "assets/[name]-[hash]",
|
|
49
48
|
bundle: true,
|
|
50
49
|
format: "esm",
|
|
51
|
-
loader:
|
|
50
|
+
loader: r.config.esbuild?.loaders || defaultLoaders(),
|
|
52
51
|
metafile: true,
|
|
53
|
-
minify:
|
|
52
|
+
minify: r.config.flags.minify,
|
|
54
53
|
platform: "browser",
|
|
55
|
-
plugins:
|
|
54
|
+
plugins: r.config.esbuild?.plugins?.length ? [p, ...r.config.esbuild?.plugins] : [p],
|
|
56
55
|
splitting: true,
|
|
57
56
|
treeShaking: true,
|
|
58
57
|
write: true
|
|
@@ -78,11 +77,8 @@ function workersPlugin(r) {
|
|
|
78
77
|
return {
|
|
79
78
|
name: "@eighty4/dank/esbuild/workers",
|
|
80
79
|
setup(build) {
|
|
81
|
-
if (!build.initialOptions.absWorkingDir)
|
|
82
|
-
throw TypeError("plugin requires absWorkingDir");
|
|
83
80
|
if (!build.initialOptions.metafile)
|
|
84
81
|
throw TypeError("plugin requires metafile");
|
|
85
|
-
const { absWorkingDir } = build.initialOptions;
|
|
86
82
|
build.onLoad({ filter: /\.(t|m?j)s$/ }, async (args) => {
|
|
87
83
|
let contents = await readFile(args.path, "utf8");
|
|
88
84
|
let offset = 0;
|
|
@@ -97,7 +93,7 @@ function workersPlugin(r) {
|
|
|
97
93
|
if (isIndexCommented(contents, workerCtorMatch.index)) {
|
|
98
94
|
continue;
|
|
99
95
|
}
|
|
100
|
-
const clientScript = args.path.replace(
|
|
96
|
+
const clientScript = args.path.replace(r.dirs.projectResolved, "").substring(1);
|
|
101
97
|
const workerUrl = workerCtorMatch.groups.url.substring(1, workerCtorMatch.groups.url.length - 1);
|
|
102
98
|
const workerEntryPoint = r.resolver.resolveHrefInPagesDir(clientScript, workerUrl);
|
|
103
99
|
if (workerEntryPoint === "outofbounds") {
|
|
@@ -106,13 +102,15 @@ function workersPlugin(r) {
|
|
|
106
102
|
errors.push(outofboundsWorkerUrlCtorArg(locationFromMatch(args, contents, workerCtorMatch), workerCtorMatch));
|
|
107
103
|
continue;
|
|
108
104
|
}
|
|
105
|
+
const workerCtor = workerCtorMatch.groups.ctor;
|
|
109
106
|
const workerUrlPlaceholder = workerEntryPoint.replace(/^pages/, "").replace(/\.(t|m?j)s$/, ".js");
|
|
110
|
-
const workerCtorReplacement = `new ${
|
|
107
|
+
const workerCtorReplacement = `new ${workerCtor}('${workerUrlPlaceholder}'${workerCtorMatch.groups.end}`;
|
|
111
108
|
contents = contents.substring(0, workerCtorMatch.index + offset) + workerCtorReplacement + contents.substring(workerCtorMatch.index + workerCtorMatch[0].length + offset);
|
|
112
109
|
offset += workerCtorReplacement.length - workerCtorMatch[0].length;
|
|
113
110
|
r.addWorker({
|
|
114
111
|
clientScript,
|
|
115
112
|
workerEntryPoint,
|
|
113
|
+
workerCtor,
|
|
116
114
|
workerUrl,
|
|
117
115
|
workerUrlPlaceholder
|
|
118
116
|
});
|
package/lib_js/flags.js
CHANGED
|
@@ -1,71 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
dirs: defaultProjectDirs(cwd()),
|
|
6
|
-
minify: willMinify(),
|
|
7
|
-
production: isProductionBuild()
|
|
8
|
-
};
|
|
9
|
-
return {
|
|
10
|
-
get dirs() {
|
|
11
|
-
return flags.dirs;
|
|
12
|
-
},
|
|
13
|
-
get minify() {
|
|
14
|
-
return flags.minify;
|
|
15
|
-
},
|
|
16
|
-
get production() {
|
|
17
|
-
return flags.production;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function resolveServeFlags(c) {
|
|
22
|
-
const preview = isPreviewBuild();
|
|
23
|
-
const flags = {
|
|
24
|
-
dirs: defaultProjectDirs(cwd()),
|
|
25
|
-
dankPort: dankPort(c, preview),
|
|
26
|
-
esbuildPort: esbuildPort(c),
|
|
1
|
+
function resolveFlags() {
|
|
2
|
+
return Object.freeze({
|
|
3
|
+
dankPort: resolveDankPort(),
|
|
4
|
+
esbuildPort: resolveEsbuildPort(),
|
|
27
5
|
logHttp: willLogHttp(),
|
|
28
6
|
minify: willMinify(),
|
|
29
|
-
preview,
|
|
7
|
+
preview: isPreviewBuild(),
|
|
30
8
|
production: isProductionBuild()
|
|
31
|
-
};
|
|
32
|
-
return {
|
|
33
|
-
get dirs() {
|
|
34
|
-
return flags.dirs;
|
|
35
|
-
},
|
|
36
|
-
get dankPort() {
|
|
37
|
-
return flags.dankPort;
|
|
38
|
-
},
|
|
39
|
-
get esbuildPort() {
|
|
40
|
-
return flags.esbuildPort;
|
|
41
|
-
},
|
|
42
|
-
get logHttp() {
|
|
43
|
-
return flags.logHttp;
|
|
44
|
-
},
|
|
45
|
-
get minify() {
|
|
46
|
-
return flags.minify;
|
|
47
|
-
},
|
|
48
|
-
get preview() {
|
|
49
|
-
return flags.preview;
|
|
50
|
-
},
|
|
51
|
-
get production() {
|
|
52
|
-
return flags.production;
|
|
53
|
-
}
|
|
54
|
-
};
|
|
9
|
+
});
|
|
55
10
|
}
|
|
56
11
|
const isPreviewBuild = () => process.env.PREVIEW === "true" || process.argv.includes("--preview");
|
|
57
12
|
const isProductionBuild = () => process.env.PRODUCTION === "true" || process.argv.includes("--production");
|
|
58
|
-
function
|
|
13
|
+
function resolveDankPort() {
|
|
59
14
|
if (process.env.DANK_PORT?.length) {
|
|
60
15
|
return parsePortEnvVar("DANK_PORT");
|
|
61
16
|
}
|
|
62
|
-
return preview ? c.previewPort || c.port || 4e3 : c.port || 3e3;
|
|
63
17
|
}
|
|
64
|
-
function
|
|
18
|
+
function resolveEsbuildPort() {
|
|
65
19
|
if (process.env.ESBUILD_PORT?.length) {
|
|
66
20
|
return parsePortEnvVar("ESBUILD_PORT");
|
|
67
21
|
}
|
|
68
|
-
return c.esbuild?.port || 3995;
|
|
69
22
|
}
|
|
70
23
|
function parsePortEnvVar(name) {
|
|
71
24
|
const port = parseInt(process.env[name], 10);
|
|
@@ -75,50 +28,8 @@ function parsePortEnvVar(name) {
|
|
|
75
28
|
return port;
|
|
76
29
|
}
|
|
77
30
|
}
|
|
78
|
-
function defaultProjectDirs(projectRootAbs) {
|
|
79
|
-
const pages = "pages";
|
|
80
|
-
const dirs = {
|
|
81
|
-
buildRoot: "build",
|
|
82
|
-
buildDist: join("build", "dist"),
|
|
83
|
-
buildWatch: join("build", "watch"),
|
|
84
|
-
pages,
|
|
85
|
-
pagesResolved: resolve(join(projectRootAbs, pages)),
|
|
86
|
-
projectResolved: resolve(projectRootAbs),
|
|
87
|
-
projectRootAbs,
|
|
88
|
-
public: "public"
|
|
89
|
-
};
|
|
90
|
-
return {
|
|
91
|
-
get buildRoot() {
|
|
92
|
-
return dirs.buildRoot;
|
|
93
|
-
},
|
|
94
|
-
get buildDist() {
|
|
95
|
-
return dirs.buildDist;
|
|
96
|
-
},
|
|
97
|
-
get buildWatch() {
|
|
98
|
-
return dirs.buildWatch;
|
|
99
|
-
},
|
|
100
|
-
get pages() {
|
|
101
|
-
return dirs.pages;
|
|
102
|
-
},
|
|
103
|
-
get pagesResolved() {
|
|
104
|
-
return dirs.pagesResolved;
|
|
105
|
-
},
|
|
106
|
-
get projectResolved() {
|
|
107
|
-
return dirs.projectResolved;
|
|
108
|
-
},
|
|
109
|
-
get projectRootAbs() {
|
|
110
|
-
return dirs.projectRootAbs;
|
|
111
|
-
},
|
|
112
|
-
get public() {
|
|
113
|
-
return dirs.public;
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
31
|
const willMinify = () => isProductionBuild() || process.env.MINIFY === "true" || process.argv.includes("--minify");
|
|
118
32
|
const willLogHttp = () => process.env.LOG_HTTP === "true" || process.argv.includes("--log-http");
|
|
119
33
|
export {
|
|
120
|
-
|
|
121
|
-
isProductionBuild,
|
|
122
|
-
resolveBuildFlags,
|
|
123
|
-
resolveServeFlags
|
|
34
|
+
resolveFlags
|
|
124
35
|
};
|