Skip to content

Commit c0ea525

Browse files
build: minify html, default to esm cdn.
1 parent b968a55 commit c0ea525

6 files changed

Lines changed: 216 additions & 13 deletions

File tree

.github/workflows/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
run: npm ci
3333

3434
- name: Build Production Site
35-
run: npm run build:esm
35+
run: npm run build
3636

3737
- name: Setup Pages
3838
uses: actions/configure-pages@v5.0.0

docs/build-and-deploy.md

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This project uses two runtime modes:
44

55
- Local development mode: dynamic CDN resolution from `src/modules/cdn.js` with esm.sh as default.
6-
- Production mode: CDN-first build artifacts in `dist`, with `build:esm` as the current preferred deploy build.
6+
- Production mode: CDN-first build artifacts in `dist`, with `npm run build` defaulting to ESM unless `KNIGHTED_PRIMARY_CDN` is set.
77

88
## Local Development
99

@@ -29,6 +29,7 @@ Select a different production primary CDN at build time:
2929
```sh
3030
KNIGHTED_PRIMARY_CDN=esm npm run build
3131
KNIGHTED_PRIMARY_CDN=jspmGa npm run build
32+
KNIGHTED_PRIMARY_CDN=importMap npm run build
3233
```
3334

3435
Convenience scripts are also available:
@@ -44,25 +45,29 @@ npm run build:importmap-mode
4445
<!-- prettier-ignore-start -->
4546
| Mode | Resolver | Import map step | JSPM index needed | Typical use |
4647
| --- | --- | --- | --- | --- |
47-
| `importMap` | Import map in `dist/index.html` | Yes | Yes | Default production mode |
48-
| `esm` | `src/modules/cdn.js` (`esm.sh` primary) | No | No | Stable fallback mode |
48+
| `importMap` | Import map in `dist/index.html` | Yes | Yes | JSPM-indexed release builds |
49+
| `esm` | `src/modules/cdn.js` (`esm.sh` primary) | No | No | Current default and deploy mode |
4950
| `jspmGa` | `src/modules/cdn.js` (`ga.jspm.io` primary) | No | No | Direct ga.jspm.io testing |
5051
<!-- prettier-ignore-end -->
5152

5253
Mode notes:
5354

5455
- `importMap`: Import-map mode when JSPM has indexed the required graph.
55-
- `esm`: Current preferred deploy build mode.
56+
- `esm`: Current default `build` mode and preferred deploy build mode.
5657
- `jspmGa`: Direct ga.jspm.io URL mode without import-map generation.
5758

58-
This runs two steps:
59+
`npm run build` runs four steps:
5960

6061
1. `npm run build:prepare`
6162

6263
- Copies `src` to `dist`
6364
- Injects `window.__KNIGHTED_PRIMARY_CDN__` into `dist/index.html`
6465

65-
2. `npm run build:importmap`
66+
2. `npm run build:css`
67+
68+
- Bundles and minifies `dist/styles.css` with Lightning CSS
69+
70+
3. `npm run build:importmap`
6671

6772
- Runs only when `KNIGHTED_PRIMARY_CDN=importMap`
6873
- Runs `jspm link` with `--provider jspm.io`
@@ -74,6 +79,10 @@ This runs two steps:
7479
- Traces generated `dist/prod-imports.js`
7580
- Import specifiers come from `importMap` entries in `src/modules/cdn.js` (`cdnImportSpecs`)
7681

82+
4. `npm run build:html`
83+
84+
- Minifies `dist/index.html` with `html-minifier-terser`
85+
7786
Preview the built site locally:
7887

7988
```sh
@@ -86,11 +95,13 @@ End-to-end tests run against a preview build by default:
8695
npm run test:e2e
8796
```
8897

89-
This command builds with `build:esm` first, then runs Playwright against the preview server.
98+
This command forces `KNIGHTED_PRIMARY_CDN=esm` and runs `npm run build` first, then runs Playwright against the preview server.
99+
100+
`preview` also forces an ESM build (`KNIGHTED_PRIMARY_CDN=esm npm run build`) before serving `dist`.
90101

91102
## CI And Deployment
92103

93-
- CI workflow (`.github/workflows/ci.yml`) installs dependencies, runs lint, and runs `npm run build`.
104+
- CI workflow (`.github/workflows/ci.yml`) installs dependencies, runs lint, and runs `npm run build:esm`.
94105
- Deploy workflow (`.github/workflows/deploy.yml`) builds the production site and publishes `dist` to GitHub Pages.
95106

96107
## Notes

package-lock.json

Lines changed: 141 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,17 @@
2626
"build:prepare": "node scripts/build-prepare.js",
2727
"build:css": "node scripts/build-css.js",
2828
"build:importmap": "node scripts/build-importmap.js",
29-
"build": "npm run build:prepare && npm run build:css && npm run build:importmap",
29+
"build:html": "node scripts/build-html.js",
30+
"build": "node scripts/build.js",
3031
"build:esm": "KNIGHTED_PRIMARY_CDN=esm npm run build",
3132
"build:jspm": "KNIGHTED_PRIMARY_CDN=jspmGa npm run build",
3233
"build:importmap-mode": "KNIGHTED_PRIMARY_CDN=importMap npm run build",
33-
"preview": "http-server dist -a localhost -p 8081 -c-1 -o index.html",
34+
"preview": "KNIGHTED_PRIMARY_CDN=esm npm run build && http-server dist -a localhost -p 8081 -c-1 -o index.html",
3435
"check-types": "tsc -p tsconfig.json",
3536
"lint:playwright": "eslint playwright playwright.config.ts",
36-
"test:e2e": "npm run build:esm && PLAYWRIGHT_WEB_SERVER_MODE=preview PLAYWRIGHT_PORT=8081 playwright test",
37+
"test:e2e": "KNIGHTED_PRIMARY_CDN=esm npm run build && PLAYWRIGHT_WEB_SERVER_MODE=preview PLAYWRIGHT_PORT=8081 playwright test",
3738
"test:e2e:dev": "playwright test",
38-
"test:e2e:headed": "npm run build:esm && PLAYWRIGHT_WEB_SERVER_MODE=preview PLAYWRIGHT_PORT=8081 playwright test --headed",
39+
"test:e2e:headed": "KNIGHTED_PRIMARY_CDN=esm npm run build && PLAYWRIGHT_WEB_SERVER_MODE=preview PLAYWRIGHT_PORT=8081 playwright test --headed",
3940
"test": "echo \"Error: no test specified\" && exit 1",
4041
"prettier": "prettier --write .",
4142
"lint": "oxlint src scripts && npm run lint:playwright"
@@ -46,6 +47,7 @@
4647
"@typescript-eslint/parser": "^8.57.1",
4748
"eslint": "^10.0.3",
4849
"eslint-plugin-playwright": "^2.10.0",
50+
"html-minifier-terser": "^7.2.0",
4951
"http-server": "^14.1.1",
5052
"husky": "^9.1.7",
5153
"jspm": "^4.4.0",

scripts/build-html.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { access, readFile, writeFile } from 'node:fs/promises'
2+
import { dirname, resolve } from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
import { minify } from 'html-minifier-terser'
5+
6+
const __dirname = dirname(fileURLToPath(import.meta.url))
7+
const projectRoot = resolve(__dirname, '..')
8+
const distIndexHtml = resolve(projectRoot, 'dist', 'index.html')
9+
10+
await access(distIndexHtml)
11+
12+
const html = await readFile(distIndexHtml, 'utf8')
13+
14+
const minifiedHtml = await minify(html, {
15+
collapseWhitespace: true,
16+
conservativeCollapse: true,
17+
removeComments: true,
18+
removeRedundantAttributes: true,
19+
removeEmptyAttributes: false,
20+
minifyCSS: true,
21+
})
22+
23+
await writeFile(distIndexHtml, minifiedHtml)

scripts/build.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { spawnSync } from 'node:child_process'
2+
3+
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm'
4+
const env = {
5+
...process.env,
6+
KNIGHTED_PRIMARY_CDN: process.env.KNIGHTED_PRIMARY_CDN ?? 'esm',
7+
}
8+
const run = script => {
9+
const result = spawnSync(npmCommand, ['run', script], {
10+
stdio: 'inherit',
11+
env,
12+
})
13+
14+
if (result.status !== 0) {
15+
process.exit(result.status ?? 1)
16+
}
17+
}
18+
19+
/*
20+
* Order matters: prepare/create dist first, then mutate assets,
21+
* and run HTML minification last after any index.html injection.
22+
*/
23+
run('build:prepare')
24+
run('build:css')
25+
run('build:importmap')
26+
run('build:html')

0 commit comments

Comments
 (0)