@eighty4/dank 0.0.3 → 0.0.4-1
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/esbuild.js +8 -5
- package/lib/build.ts +133 -72
- package/lib/{tag.ts → build_tag.ts} +3 -3
- package/lib/dank.ts +147 -11
- package/lib/define.ts +4 -5
- package/lib/esbuild.ts +239 -60
- package/lib/flags.ts +154 -10
- package/lib/html.ts +320 -116
- package/lib/http.ts +195 -47
- package/lib/metadata.ts +309 -0
- package/lib/public.ts +21 -13
- package/lib/serve.ts +205 -144
- package/lib/services.ts +28 -4
- package/lib_js/build.js +82 -57
- package/lib_js/{tag.js → build_tag.js} +2 -3
- package/lib_js/dank.js +73 -5
- package/lib_js/define.js +3 -5
- package/lib_js/esbuild.js +166 -54
- package/lib_js/flags.js +123 -8
- package/lib_js/html.js +197 -87
- package/lib_js/http.js +111 -30
- package/lib_js/metadata.js +210 -0
- package/lib_js/public.js +19 -11
- package/lib_js/serve.js +135 -110
- package/lib_js/services.js +13 -2
- package/lib_types/dank.d.ts +18 -1
- package/package.json +7 -1
- package/lib/manifest.ts +0 -61
- package/lib_js/manifest.js +0 -37
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { exec } from 'node:child_process';
|
|
2
|
-
|
|
3
|
-
export async function createBuildTag() {
|
|
2
|
+
export async function createBuildTag(build) {
|
|
4
3
|
const now = new Date();
|
|
5
4
|
const ms = now.getUTCMilliseconds() +
|
|
6
5
|
now.getUTCSeconds() * 1000 +
|
|
@@ -9,7 +8,7 @@ export async function createBuildTag() {
|
|
|
9
8
|
const date = now.toISOString().substring(0, 10);
|
|
10
9
|
const time = String(ms).padStart(8, '0');
|
|
11
10
|
const when = `${date}-${time}`;
|
|
12
|
-
if (
|
|
11
|
+
if (build.production) {
|
|
13
12
|
const gitHash = await new Promise((res, rej) => exec('git rev-parse --short HEAD', (err, stdout) => {
|
|
14
13
|
if (err)
|
|
15
14
|
rej(err);
|
package/lib_js/dank.js
CHANGED
|
@@ -1,21 +1,76 @@
|
|
|
1
1
|
export async function defineConfig(c) {
|
|
2
|
+
if (c.port !== null && typeof c.port !== 'undefined') {
|
|
3
|
+
if (typeof c.port !== 'number') {
|
|
4
|
+
throw Error('DankConfig.port must be a number');
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
if (c.previewPort !== null && typeof c.previewPort !== 'undefined') {
|
|
8
|
+
if (typeof c.previewPort !== 'number') {
|
|
9
|
+
throw Error('DankConfig.previewPort must be a number');
|
|
10
|
+
}
|
|
11
|
+
}
|
|
2
12
|
validatePages(c.pages);
|
|
3
13
|
validateDevServices(c.services);
|
|
14
|
+
validateEsbuildConfig(c.esbuild);
|
|
4
15
|
normalizePagePaths(c.pages);
|
|
5
16
|
return c;
|
|
6
17
|
}
|
|
18
|
+
function validateEsbuildConfig(esbuild) {
|
|
19
|
+
if (esbuild?.loaders !== null && typeof esbuild?.loaders !== 'undefined') {
|
|
20
|
+
if (typeof esbuild.loaders !== 'object') {
|
|
21
|
+
throw Error('DankConfig.esbuild.loaders must be a map of extensions to esbuild loaders');
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
for (const [ext, loader] of Object.entries(esbuild.loaders)) {
|
|
25
|
+
if (typeof loader !== 'string') {
|
|
26
|
+
throw Error(`DankConfig.esbuild.loaders['${ext}'] must be a string of a loader name`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (esbuild?.plugins !== null && typeof esbuild?.plugins !== 'undefined') {
|
|
32
|
+
if (!Array.isArray(esbuild.plugins)) {
|
|
33
|
+
throw Error('DankConfig.esbuild.plugins must be an array of esbuild plugins');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (esbuild?.port !== null && typeof esbuild?.port !== 'undefined') {
|
|
37
|
+
if (typeof esbuild.port !== 'number') {
|
|
38
|
+
throw Error('DankConfig.esbuild.port must be a number');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
7
42
|
function validatePages(pages) {
|
|
8
43
|
if (pages === null ||
|
|
9
44
|
typeof pages === 'undefined' ||
|
|
10
45
|
Object.keys(pages).length === 0) {
|
|
11
46
|
throw Error('DankConfig.pages is required');
|
|
12
47
|
}
|
|
13
|
-
for (const [urlPath,
|
|
14
|
-
if (typeof
|
|
15
|
-
|
|
48
|
+
for (const [urlPath, mapping] of Object.entries(pages)) {
|
|
49
|
+
if (typeof mapping === 'string' && mapping.endsWith('.html')) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (typeof mapping === 'object') {
|
|
53
|
+
validatePageMapping(urlPath, mapping);
|
|
54
|
+
continue;
|
|
16
55
|
}
|
|
56
|
+
throw Error(`DankConfig.pages['${urlPath}'] must configure an html file`);
|
|
17
57
|
}
|
|
18
58
|
}
|
|
59
|
+
function validatePageMapping(urlPath, mapping) {
|
|
60
|
+
if (mapping.webpage === null ||
|
|
61
|
+
typeof mapping.webpage !== 'string' ||
|
|
62
|
+
!mapping.webpage.endsWith('.html')) {
|
|
63
|
+
throw Error(`DankConfig.pages['${urlPath}'].webpage must configure an html file`);
|
|
64
|
+
}
|
|
65
|
+
if (mapping.pattern === null || typeof mapping.pattern === 'undefined') {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
if (typeof mapping.pattern === 'object' &&
|
|
69
|
+
mapping.pattern.constructor.name === 'RegExp') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw Error(`DankConfig.pages['${urlPath}'].pattern must be a RegExp`);
|
|
73
|
+
}
|
|
19
74
|
function validateDevServices(services) {
|
|
20
75
|
if (services === null || typeof services === 'undefined') {
|
|
21
76
|
return;
|
|
@@ -46,10 +101,23 @@ function validateDevServices(services) {
|
|
|
46
101
|
}
|
|
47
102
|
}
|
|
48
103
|
}
|
|
104
|
+
if (s.http !== null && typeof s.http !== 'undefined') {
|
|
105
|
+
if (typeof s.http.port !== 'number') {
|
|
106
|
+
throw Error(`DankConfig.services[${i}].http.port must be a number`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
49
109
|
}
|
|
50
110
|
}
|
|
51
111
|
function normalizePagePaths(pages) {
|
|
52
|
-
for (const
|
|
53
|
-
|
|
112
|
+
for (const [pageUrl, mapping] of Object.entries(pages)) {
|
|
113
|
+
if (typeof mapping === 'string') {
|
|
114
|
+
pages[pageUrl] = normalizePagePath(mapping);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
mapping.webpage = normalizePagePath(mapping.webpage);
|
|
118
|
+
}
|
|
54
119
|
}
|
|
55
120
|
}
|
|
121
|
+
function normalizePagePath(p) {
|
|
122
|
+
return p.replace(/^\.\//, '');
|
|
123
|
+
}
|
package/lib_js/define.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
export function createGlobalDefinitions() {
|
|
3
|
-
const isProduction = isProductionBuild();
|
|
1
|
+
export function createGlobalDefinitions(build) {
|
|
4
2
|
return {
|
|
5
|
-
'dank.IS_DEV': JSON.stringify(!
|
|
6
|
-
'dank.IS_PROD': JSON.stringify(
|
|
3
|
+
'dank.IS_DEV': JSON.stringify(!build.production),
|
|
4
|
+
'dank.IS_PROD': JSON.stringify(build.production),
|
|
7
5
|
};
|
|
8
6
|
}
|
package/lib_js/esbuild.js
CHANGED
|
@@ -1,50 +1,75 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
1
2
|
import esbuild, {} from 'esbuild';
|
|
2
|
-
|
|
3
|
-
const jsBuildOptions = {
|
|
4
|
-
bundle: true,
|
|
5
|
-
metafile: true,
|
|
6
|
-
minify: willMinify(),
|
|
7
|
-
platform: 'browser',
|
|
8
|
-
splitting: false,
|
|
9
|
-
treeShaking: true,
|
|
10
|
-
write: true,
|
|
11
|
-
};
|
|
12
|
-
const webpageBuildOptions = {
|
|
13
|
-
assetNames: 'assets/[name]-[hash]',
|
|
14
|
-
format: 'esm',
|
|
15
|
-
loader: {
|
|
16
|
-
'.tff': 'file',
|
|
17
|
-
'.woff': 'file',
|
|
18
|
-
'.woff2': 'file',
|
|
19
|
-
},
|
|
20
|
-
...jsBuildOptions,
|
|
21
|
-
};
|
|
22
|
-
export async function esbuildDevContext(define, entryPoints, outdir) {
|
|
3
|
+
export async function esbuildDevContext(b, r, define, entryPoints, c) {
|
|
23
4
|
return await esbuild.context({
|
|
24
5
|
define,
|
|
25
6
|
entryNames: '[dir]/[name]',
|
|
26
|
-
entryPoints:
|
|
27
|
-
outdir,
|
|
28
|
-
...
|
|
29
|
-
|
|
7
|
+
entryPoints: mapEntryPointPaths(entryPoints),
|
|
8
|
+
outdir: b.dirs.buildWatch,
|
|
9
|
+
...commonBuildOptions(b, r, c),
|
|
10
|
+
splitting: false,
|
|
30
11
|
write: false,
|
|
31
12
|
});
|
|
32
13
|
}
|
|
33
|
-
export async function esbuildWebpages(define, entryPoints,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
14
|
+
export async function esbuildWebpages(b, r, define, entryPoints, c) {
|
|
15
|
+
try {
|
|
16
|
+
await esbuild.build({
|
|
17
|
+
define,
|
|
18
|
+
entryNames: '[dir]/[name]-[hash]',
|
|
19
|
+
entryPoints: mapEntryPointPaths(entryPoints),
|
|
20
|
+
outdir: b.dirs.buildDist,
|
|
21
|
+
...commonBuildOptions(b, r, c),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
catch (ignore) {
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function esbuildWorkers(b, r, define, entryPoints, c) {
|
|
29
|
+
try {
|
|
30
|
+
await esbuild.build({
|
|
31
|
+
define,
|
|
32
|
+
entryNames: '[dir]/[name]-[hash]',
|
|
33
|
+
entryPoints: mapEntryPointPaths(entryPoints),
|
|
34
|
+
outdir: b.dirs.buildDist,
|
|
35
|
+
...commonBuildOptions(b, r, c),
|
|
36
|
+
splitting: false,
|
|
37
|
+
metafile: true,
|
|
38
|
+
write: true,
|
|
39
|
+
assetNames: 'assets/[name]-[hash]',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (ignore) {
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function commonBuildOptions(b, r, c) {
|
|
47
|
+
const p = workersPlugin(r.buildRegistry());
|
|
48
|
+
return {
|
|
49
|
+
absWorkingDir: b.dirs.projectRootAbs,
|
|
50
|
+
assetNames: 'assets/[name]-[hash]',
|
|
51
|
+
bundle: true,
|
|
52
|
+
format: 'esm',
|
|
53
|
+
loader: c?.loaders || defaultLoaders(),
|
|
54
|
+
metafile: true,
|
|
55
|
+
minify: b.minify,
|
|
56
|
+
platform: 'browser',
|
|
57
|
+
plugins: c?.plugins?.length ? [p, ...c.plugins] : [p],
|
|
58
|
+
splitting: true,
|
|
59
|
+
treeShaking: true,
|
|
60
|
+
write: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function defaultLoaders() {
|
|
64
|
+
return {
|
|
65
|
+
'.woff': 'file',
|
|
66
|
+
'.woff2': 'file',
|
|
67
|
+
};
|
|
43
68
|
}
|
|
44
69
|
// esbuild will append the .js or .css to output filenames
|
|
45
70
|
// keeping extension on entryPoints data for consistency
|
|
46
|
-
// and
|
|
47
|
-
function
|
|
71
|
+
// and only trimming when creating esbuild opts
|
|
72
|
+
function mapEntryPointPaths(entryPoints) {
|
|
48
73
|
return entryPoints.map(entryPoint => {
|
|
49
74
|
return {
|
|
50
75
|
in: entryPoint.in,
|
|
@@ -52,23 +77,110 @@ function removeEntryPointOutExt(entryPoints) {
|
|
|
52
77
|
};
|
|
53
78
|
});
|
|
54
79
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
const WORKER_CTOR_REGEX = /new(?:\s|\r?\n)+(?<ctor>(?:Shared)?Worker)(?:\s|\r?\n)*\((?:\s|\r?\n)*(?<url>.*?)(?:\s|\r?\n)*(?<end>[\),])/g;
|
|
81
|
+
const WORKER_URL_REGEX = /^('.*'|".*")$/;
|
|
82
|
+
export function workersPlugin(r) {
|
|
83
|
+
return {
|
|
84
|
+
name: '@eighty4/dank/esbuild/workers',
|
|
85
|
+
setup(build) {
|
|
86
|
+
if (!build.initialOptions.absWorkingDir)
|
|
87
|
+
throw TypeError('plugin requires absWorkingDir');
|
|
88
|
+
if (!build.initialOptions.metafile)
|
|
89
|
+
throw TypeError('plugin requires metafile');
|
|
90
|
+
const { absWorkingDir } = build.initialOptions;
|
|
91
|
+
build.onLoad({ filter: /\.(t|m?j)s$/ }, async (args) => {
|
|
92
|
+
let contents = await readFile(args.path, 'utf8');
|
|
93
|
+
let offset = 0;
|
|
94
|
+
let errors = undefined;
|
|
95
|
+
for (const workerCtorMatch of contents.matchAll(WORKER_CTOR_REGEX)) {
|
|
96
|
+
if (!WORKER_URL_REGEX.test(workerCtorMatch.groups.url)) {
|
|
97
|
+
if (!errors)
|
|
98
|
+
errors = [];
|
|
99
|
+
errors.push(invalidWorkerUrlCtorArg(locationFromMatch(args, contents, workerCtorMatch), workerCtorMatch));
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (isIndexCommented(contents, workerCtorMatch.index)) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const clientScript = args.path
|
|
106
|
+
.replace(absWorkingDir, '')
|
|
107
|
+
.substring(1);
|
|
108
|
+
const workerUrl = workerCtorMatch.groups.url.substring(1, workerCtorMatch.groups.url.length - 1);
|
|
109
|
+
const workerEntryPoint = r.resolver.resolveHrefInPagesDir(clientScript, workerUrl);
|
|
110
|
+
if (workerEntryPoint === 'outofbounds') {
|
|
111
|
+
if (!errors)
|
|
112
|
+
errors = [];
|
|
113
|
+
errors.push(outofboundsWorkerUrlCtorArg(locationFromMatch(args, contents, workerCtorMatch), workerCtorMatch));
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
const workerUrlPlaceholder = workerEntryPoint
|
|
117
|
+
.replace(/^pages/, '')
|
|
118
|
+
.replace(/\.(t|m?j)s$/, '.js');
|
|
119
|
+
const workerCtorReplacement = `new ${workerCtorMatch.groups.ctor}('${workerUrlPlaceholder}'${workerCtorMatch.groups.end}`;
|
|
120
|
+
contents =
|
|
121
|
+
contents.substring(0, workerCtorMatch.index + offset) +
|
|
122
|
+
workerCtorReplacement +
|
|
123
|
+
contents.substring(workerCtorMatch.index +
|
|
124
|
+
workerCtorMatch[0].length +
|
|
125
|
+
offset);
|
|
126
|
+
offset +=
|
|
127
|
+
workerCtorReplacement.length - workerCtorMatch[0].length;
|
|
128
|
+
r.addWorker({
|
|
129
|
+
clientScript,
|
|
130
|
+
workerEntryPoint,
|
|
131
|
+
workerUrl,
|
|
132
|
+
workerUrlPlaceholder,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
const loader = args.path.endsWith('ts') ? 'ts' : 'js';
|
|
136
|
+
return { contents, errors, loader };
|
|
137
|
+
});
|
|
138
|
+
build.onEnd((result) => {
|
|
139
|
+
if (result.metafile) {
|
|
140
|
+
r.completeBuild(result);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function isIndexCommented(contents, index) {
|
|
147
|
+
const preamble = contents.substring(0, index);
|
|
148
|
+
const lineIndex = preamble.lastIndexOf('\n') || 0;
|
|
149
|
+
const lineCommented = /\/\//.test(preamble.substring(lineIndex));
|
|
150
|
+
if (lineCommented) {
|
|
151
|
+
return true;
|
|
62
152
|
}
|
|
153
|
+
const blockCommentIndex = preamble.lastIndexOf('/*');
|
|
154
|
+
const blockCommented = blockCommentIndex !== -1 &&
|
|
155
|
+
preamble.substring(blockCommentIndex).indexOf('*/') === -1;
|
|
156
|
+
return blockCommented;
|
|
63
157
|
}
|
|
64
|
-
function
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
158
|
+
function locationFromMatch(args, contents, match) {
|
|
159
|
+
const preamble = contents.substring(0, match.index);
|
|
160
|
+
const line = preamble.match(/\n/g)?.length || 0;
|
|
161
|
+
let lineIndex = preamble.lastIndexOf('\n');
|
|
162
|
+
lineIndex = lineIndex === -1 ? 0 : lineIndex + 1;
|
|
163
|
+
const column = preamble.length - lineIndex;
|
|
164
|
+
const lineText = contents.substring(lineIndex, contents.indexOf('\n', lineIndex) || contents.length);
|
|
165
|
+
return {
|
|
166
|
+
lineText,
|
|
167
|
+
line,
|
|
168
|
+
column,
|
|
169
|
+
file: args.path,
|
|
170
|
+
length: match[0].length,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function outofboundsWorkerUrlCtorArg(location, workerCtorMatch) {
|
|
174
|
+
return {
|
|
175
|
+
id: 'worker-url-outofbounds',
|
|
176
|
+
text: `The ${workerCtorMatch.groups.ctor} constructor URL arg \`${workerCtorMatch.groups.url}\` cannot resolve to a path outside of the pages directory`,
|
|
177
|
+
location,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function invalidWorkerUrlCtorArg(location, workerCtorMatch) {
|
|
181
|
+
return {
|
|
182
|
+
id: 'worker-url-unresolvable',
|
|
183
|
+
text: `The ${workerCtorMatch.groups.ctor} constructor URL arg \`${workerCtorMatch.groups.url}\` must be a relative module path`,
|
|
184
|
+
location,
|
|
185
|
+
};
|
|
74
186
|
}
|
package/lib_js/flags.js
CHANGED
|
@@ -1,13 +1,128 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { join, resolve } from 'node:path';
|
|
2
|
+
import { cwd } from 'node:process';
|
|
3
|
+
export function resolveBuildFlags() {
|
|
4
|
+
const flags = {
|
|
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
|
+
export function resolveServeFlags(c) {
|
|
22
|
+
const preview = isPreviewBuild();
|
|
23
|
+
const flags = {
|
|
24
|
+
dirs: defaultProjectDirs(cwd()),
|
|
25
|
+
dankPort: dankPort(c, preview),
|
|
26
|
+
esbuildPort: esbuildPort(c),
|
|
27
|
+
logHttp: willLogHttp(),
|
|
28
|
+
minify: willMinify(),
|
|
29
|
+
preview,
|
|
30
|
+
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
|
+
};
|
|
55
|
+
}
|
|
3
56
|
// `dank serve` will pre-bundle and use service worker
|
|
4
|
-
|
|
57
|
+
const isPreviewBuild = () => process.env.PREVIEW === 'true' || process.argv.includes('--preview');
|
|
5
58
|
// `dank build` will minify sources and append git release tag to build tag
|
|
6
59
|
// `dank serve` will pre-bundle with service worker and minify
|
|
7
|
-
|
|
8
|
-
|
|
60
|
+
const isProductionBuild = () => process.env.PRODUCTION === 'true' || process.argv.includes('--production');
|
|
61
|
+
// `dank serve` dank port for frontend webserver
|
|
62
|
+
// alternate --preview port for service worker builds
|
|
63
|
+
function dankPort(c, preview) {
|
|
64
|
+
if (process.env.DANK_PORT?.length) {
|
|
65
|
+
return parsePortEnvVar('DANK_PORT');
|
|
66
|
+
}
|
|
67
|
+
return preview ? c.previewPort || c.port || 4000 : c.port || 3000;
|
|
68
|
+
}
|
|
69
|
+
// `dank serve` esbuild port for bundler integration
|
|
70
|
+
function esbuildPort(c) {
|
|
71
|
+
if (process.env.ESBUILD_PORT?.length) {
|
|
72
|
+
return parsePortEnvVar('ESBUILD_PORT');
|
|
73
|
+
}
|
|
74
|
+
return c.esbuild?.port || 3995;
|
|
75
|
+
}
|
|
76
|
+
function parsePortEnvVar(name) {
|
|
77
|
+
const port = parseInt(process.env[name], 10);
|
|
78
|
+
if (isNaN(port)) {
|
|
79
|
+
throw Error(`env var ${name}=${port} must be a valid port number`);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return port;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export function defaultProjectDirs(projectRootAbs) {
|
|
86
|
+
const pages = 'pages';
|
|
87
|
+
const dirs = {
|
|
88
|
+
buildRoot: 'build',
|
|
89
|
+
buildDist: join('build', 'dist'),
|
|
90
|
+
buildWatch: join('build', 'watch'),
|
|
91
|
+
pages,
|
|
92
|
+
pagesResolved: resolve(join(projectRootAbs, pages)),
|
|
93
|
+
projectResolved: resolve(projectRootAbs),
|
|
94
|
+
projectRootAbs,
|
|
95
|
+
public: 'public',
|
|
96
|
+
};
|
|
97
|
+
return {
|
|
98
|
+
get buildRoot() {
|
|
99
|
+
return dirs.buildRoot;
|
|
100
|
+
},
|
|
101
|
+
get buildDist() {
|
|
102
|
+
return dirs.buildDist;
|
|
103
|
+
},
|
|
104
|
+
get buildWatch() {
|
|
105
|
+
return dirs.buildWatch;
|
|
106
|
+
},
|
|
107
|
+
get pages() {
|
|
108
|
+
return dirs.pages;
|
|
109
|
+
},
|
|
110
|
+
get pagesResolved() {
|
|
111
|
+
return dirs.pagesResolved;
|
|
112
|
+
},
|
|
113
|
+
get projectResolved() {
|
|
114
|
+
return dirs.projectResolved;
|
|
115
|
+
},
|
|
116
|
+
get projectRootAbs() {
|
|
117
|
+
return dirs.projectRootAbs;
|
|
118
|
+
},
|
|
119
|
+
get public() {
|
|
120
|
+
return dirs.public;
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const willMinify = () => isProductionBuild() ||
|
|
9
125
|
process.env.MINIFY === 'true' ||
|
|
10
126
|
process.argv.includes('--minify');
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
process.argv.includes('--tsc');
|
|
127
|
+
// `dank serve` will print http access logs to console
|
|
128
|
+
const willLogHttp = () => process.env.LOG_HTTP === 'true' || process.argv.includes('--log-http');
|