@eighty4/dank 0.0.1-3 → 0.0.1-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/README.md +61 -0
- package/lib/build.ts +1 -1
- package/lib/esbuild.ts +5 -0
- package/lib/html.ts +11 -3
- package/lib/http.ts +6 -0
- package/lib_js/build.js +1 -1
- package/lib_js/esbuild.js +5 -0
- package/lib_js/html.js +8 -3
- package/lib_js/http.js +6 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Build DANK webpages
|
|
2
|
+
|
|
3
|
+
DANK has some perks:
|
|
4
|
+
|
|
5
|
+
- Webpage-first development for multi-page websites
|
|
6
|
+
- Code splitting via `esbuild` bundler across all webpages
|
|
7
|
+
- `dank serve` updates CSS in real-time (hot-reloading)
|
|
8
|
+
- `dank serve` launches development processes and merges their stdio
|
|
9
|
+
- `dank serve --preview` builds the website and serves the output from `dist`
|
|
10
|
+
- `dank build --production` optimizes with `esbuild` minifying and tree-shaking
|
|
11
|
+
- DANK's codebase is so tiny you can read it all in 20 mins
|
|
12
|
+
|
|
13
|
+
DANK isn't for every use case.
|
|
14
|
+
[Vite](https://vite.dev) is the right move for building a Single-Page Application.
|
|
15
|
+
For SEO optimizing dynamic content with Server-Side Rendering,
|
|
16
|
+
check out [Next.js](https://nextjs.org) or [Astro](https://astro.build).
|
|
17
|
+
|
|
18
|
+
DANK is an ideal choice for building multi-page websites deployed to a CDN.
|
|
19
|
+
|
|
20
|
+
## Getting started
|
|
21
|
+
|
|
22
|
+
```shell
|
|
23
|
+
bun create dank --out-dir www
|
|
24
|
+
|
|
25
|
+
npm create dank -- --out-dir www
|
|
26
|
+
|
|
27
|
+
pnpm create dank --out-dir www
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## `dank.config.ts` examples
|
|
31
|
+
|
|
32
|
+
Webpages and their URLs are configured explicitly to keep your URLs
|
|
33
|
+
and workspace organized independently:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { defineConfig } from '@eighty4/dank'
|
|
37
|
+
|
|
38
|
+
export default defineConfig({
|
|
39
|
+
pages: {
|
|
40
|
+
'/': './home.html',
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Streamline development with `dank serve` launching API when starting your dev server:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { defineConfig } from '@eighty4/dank'
|
|
49
|
+
|
|
50
|
+
export default defineConfig({
|
|
51
|
+
pages: {
|
|
52
|
+
'/': './home.html',
|
|
53
|
+
},
|
|
54
|
+
services: [
|
|
55
|
+
{
|
|
56
|
+
command: 'node --watch --env-file-if-exists=.env.dev server.ts',
|
|
57
|
+
cwd: './api',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
})
|
|
61
|
+
```
|
package/lib/build.ts
CHANGED
package/lib/esbuild.ts
CHANGED
|
@@ -21,6 +21,11 @@ const jsBuildOptions: BuildOptions & { metafile: true; write: true } = {
|
|
|
21
21
|
const webpageBuildOptions: BuildOptions & { metafile: true; write: true } = {
|
|
22
22
|
assetNames: 'assets/[name]-[hash]',
|
|
23
23
|
format: 'esm',
|
|
24
|
+
loader: {
|
|
25
|
+
'.tff': 'file',
|
|
26
|
+
'.woff': 'file',
|
|
27
|
+
'.woff2': 'file',
|
|
28
|
+
},
|
|
24
29
|
...jsBuildOptions,
|
|
25
30
|
}
|
|
26
31
|
|
package/lib/html.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile } from 'node:fs/promises'
|
|
2
2
|
import { dirname, join, relative } from 'node:path'
|
|
3
|
+
import { extname } from 'node:path/posix'
|
|
3
4
|
import {
|
|
4
5
|
defaultTreeAdapter,
|
|
5
6
|
type DefaultTreeAdapterTypes,
|
|
@@ -75,12 +76,12 @@ export class HtmlEntrypoint {
|
|
|
75
76
|
) {
|
|
76
77
|
importScript.elem.attrs.find(
|
|
77
78
|
attr => attr.name === 'src',
|
|
78
|
-
)!.value = rewriteTo || `/${importScript.out}
|
|
79
|
+
)!.value = rewriteTo || `/${importScript.out}`
|
|
79
80
|
}
|
|
80
81
|
} else if (importScript.type === 'style') {
|
|
81
82
|
importScript.elem.attrs.find(
|
|
82
83
|
attr => attr.name === 'href',
|
|
83
|
-
)!.value = rewriteTo || `/${importScript.out}
|
|
84
|
+
)!.value = rewriteTo || `/${importScript.out}`
|
|
84
85
|
}
|
|
85
86
|
}
|
|
86
87
|
}
|
|
@@ -182,12 +183,19 @@ export class HtmlEntrypoint {
|
|
|
182
183
|
|
|
183
184
|
#addScript(type: ImportedScript['type'], href: string, elem: Element) {
|
|
184
185
|
const inPath = join(dirname(this.#fsPath), href)
|
|
186
|
+
let outPath = inPath.replace(/^pages\//, '')
|
|
187
|
+
if (type === 'script' && !outPath.endsWith('.js')) {
|
|
188
|
+
outPath = outPath.replace(
|
|
189
|
+
new RegExp(extname(outPath).substring(1) + '$'),
|
|
190
|
+
'js',
|
|
191
|
+
)
|
|
192
|
+
}
|
|
185
193
|
this.#scripts.push({
|
|
186
194
|
type,
|
|
187
195
|
href,
|
|
188
196
|
elem,
|
|
189
197
|
in: inPath,
|
|
190
|
-
out:
|
|
198
|
+
out: outPath,
|
|
191
199
|
})
|
|
192
200
|
}
|
|
193
201
|
}
|
package/lib/http.ts
CHANGED
|
@@ -90,6 +90,12 @@ function resolveMimeType(url: URL): string {
|
|
|
90
90
|
return 'image/svg+xml'
|
|
91
91
|
case '.png':
|
|
92
92
|
return 'image/png'
|
|
93
|
+
case '.ttf':
|
|
94
|
+
return 'font/ttf'
|
|
95
|
+
case '.woff':
|
|
96
|
+
return 'font/woff'
|
|
97
|
+
case '.woff2':
|
|
98
|
+
return 'font/woff2'
|
|
93
99
|
default:
|
|
94
100
|
console.warn('? mime type for', url.pathname)
|
|
95
101
|
if (!isProductionBuild()) process.exit(1)
|
package/lib_js/build.js
CHANGED
package/lib_js/esbuild.js
CHANGED
|
@@ -12,6 +12,11 @@ const jsBuildOptions = {
|
|
|
12
12
|
const webpageBuildOptions = {
|
|
13
13
|
assetNames: 'assets/[name]-[hash]',
|
|
14
14
|
format: 'esm',
|
|
15
|
+
loader: {
|
|
16
|
+
'.tff': 'file',
|
|
17
|
+
'.woff': 'file',
|
|
18
|
+
'.woff2': 'file',
|
|
19
|
+
},
|
|
15
20
|
...jsBuildOptions,
|
|
16
21
|
};
|
|
17
22
|
export async function esbuildDevContext(define, entryPoints, outdir) {
|
package/lib_js/html.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { dirname, join, relative } from 'node:path';
|
|
3
|
+
import { extname } from 'node:path/posix';
|
|
3
4
|
import { defaultTreeAdapter, parse, parseFragment, serialize, } from 'parse5';
|
|
4
5
|
// unenforced but necessary sequence:
|
|
5
6
|
// injectPartials
|
|
@@ -44,11 +45,11 @@ export class HtmlEntrypoint {
|
|
|
44
45
|
if (importScript.type === 'script') {
|
|
45
46
|
if (importScript.in.endsWith('.tsx') ||
|
|
46
47
|
importScript.in.endsWith('.ts')) {
|
|
47
|
-
importScript.elem.attrs.find(attr => attr.name === 'src').value = rewriteTo || `/${importScript.out}
|
|
48
|
+
importScript.elem.attrs.find(attr => attr.name === 'src').value = rewriteTo || `/${importScript.out}`;
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
else if (importScript.type === 'style') {
|
|
51
|
-
importScript.elem.attrs.find(attr => attr.name === 'href').value = rewriteTo || `/${importScript.out}
|
|
52
|
+
importScript.elem.attrs.find(attr => attr.name === 'href').value = rewriteTo || `/${importScript.out}`;
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -121,12 +122,16 @@ export class HtmlEntrypoint {
|
|
|
121
122
|
}
|
|
122
123
|
#addScript(type, href, elem) {
|
|
123
124
|
const inPath = join(dirname(this.#fsPath), href);
|
|
125
|
+
let outPath = inPath.replace(/^pages\//, '');
|
|
126
|
+
if (type === 'script' && !outPath.endsWith('.js')) {
|
|
127
|
+
outPath = outPath.replace(new RegExp(extname(outPath).substring(1) + '$'), 'js');
|
|
128
|
+
}
|
|
124
129
|
this.#scripts.push({
|
|
125
130
|
type,
|
|
126
131
|
href,
|
|
127
132
|
elem,
|
|
128
133
|
in: inPath,
|
|
129
|
-
out:
|
|
134
|
+
out: outPath,
|
|
130
135
|
});
|
|
131
136
|
}
|
|
132
137
|
}
|
package/lib_js/http.js
CHANGED
|
@@ -64,6 +64,12 @@ function resolveMimeType(url) {
|
|
|
64
64
|
return 'image/svg+xml';
|
|
65
65
|
case '.png':
|
|
66
66
|
return 'image/png';
|
|
67
|
+
case '.ttf':
|
|
68
|
+
return 'font/ttf';
|
|
69
|
+
case '.woff':
|
|
70
|
+
return 'font/woff';
|
|
71
|
+
case '.woff2':
|
|
72
|
+
return 'font/woff2';
|
|
67
73
|
default:
|
|
68
74
|
console.warn('? mime type for', url.pathname);
|
|
69
75
|
if (!isProductionBuild())
|
package/package.json
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eighty4/dank",
|
|
3
|
-
"version": "0.0.1-
|
|
3
|
+
"version": "0.0.1-4",
|
|
4
4
|
"type": "module",
|
|
5
|
+
"description": "Multi-page development system for CDN-deployed websites",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"frontend",
|
|
8
|
+
"bundler",
|
|
9
|
+
"esbuild",
|
|
10
|
+
"dank"
|
|
11
|
+
],
|
|
5
12
|
"bin": "./lib_js/bin.js",
|
|
6
13
|
"exports": {
|
|
7
14
|
".": {
|