@tideworthy/tidysites 0.1.11 → 0.1.12
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 +1 -0
- package/bin/tidysites.mjs +36 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ nothing else; it lives in `.tidysites/key`, which is kept out of git.
|
|
|
24
24
|
| `tidysites push [--prune] [--force] [--dry] [--only pages]` | validate, then write the created and updated entries back (with `--prune`, delete the entries whose files are gone), then pull |
|
|
25
25
|
| `tidysites shot <path or url> [--mobile] [--tablet] [--desktop] [--wide] [--all] [--first-screen] [--live]` | a screenshot of a page of the preview site, the live site, or any address, saved under `.tidysites/shots/`; none of the width flags means desktop and mobile; a port compares all four. A page taller than 2400px comes in 1600px bands (`<name>-band-01.jpg`, …), top to bottom, that an image reader can take in one at a time. `--menu` opens every navigation menu (burgers, `<details>`, hover dropdowns) before the capture; `--open a,b` clicks those selectors and `--hover a,b` shows the submenus under them, for a popup, a tab or one dropdown |
|
|
26
26
|
| `tidysites measure <path or url> [--mobile] [--tablet] [--desktop] [--wide] [--all] [--full]` | the page as the browser lays it out: every heading, paragraph, button, picture and section box with its computed type (size, line height, weight, family, colour) and box (position, size, padding, margin, background), saved as JSON under `.tidysites/measures/` and printed. Measure the old page and the new one at the same width and style to the numbers. The same `--menu`, `--open` and `--hover` as `shot`, so a dropdown's open type is measured |
|
|
27
|
+
| `tidysites speed <path or url> [--mobile\|--desktop] [--live] [--against <url>]` | PageSpeed Insights (Google's Lighthouse) for a page of the preview or live site, or any address: scores, lab and field metrics, the largest-paint element and the opportunities with the files they name, saved under `.tidysites/speed/`. `--against <url>` tests the old page in the same call for a side-by-side. Run it on the live site before calling a build done; what the content cannot fix goes in the report |
|
|
27
28
|
| `tidysites redirect [add <old path> <new path> \| rm <old path>]` | the website's redirects: an old address that must keep working after a port goes here; they ship with the next publish |
|
|
28
29
|
| `tidysites pages` | every address the website renders |
|
|
29
30
|
| `tidysites page <path> [--html]` | the rendered page, section by section, with the key each section carries |
|
package/bin/tidysites.mjs
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* push [--prune] [--force] [--dry] write the changes back, then pull
|
|
10
10
|
* shot <path|url> [--mobile] [--tablet] [--desktop] [--wide] [--all] [--first-screen] [--menu] [--open sel,..] [--hover sel,..] screenshot to .tidysites/shots (none = desktop and mobile); a tall page comes in 1600px bands; --menu opens every navigation menu first
|
|
11
11
|
* measure <path|url> [--mobile] [--tablet] [--desktop] [--wide] [--all] [--full] [--menu] [--open sel,..] [--hover sel,..] the computed type and boxes of a page: the numbers to style to and diff
|
|
12
|
+
* speed <path|url> [--mobile|--desktop] [--live] [--against <url>] PageSpeed Insights for a page, and the old page beside it
|
|
12
13
|
* redirect [add <old> <new> | rm <old>] the website's redirects (an old address that must keep working goes here)
|
|
13
14
|
* pages every address the website renders
|
|
14
15
|
* page <path> [--html] the rendered page, section by section
|
|
@@ -434,6 +435,39 @@ async function measure(ctx) {
|
|
|
434
435
|
}
|
|
435
436
|
}
|
|
436
437
|
|
|
438
|
+
/** PageSpeed Insights for a page of the website (or any address), and the old page beside it with --against. */
|
|
439
|
+
async function speed(ctx) {
|
|
440
|
+
const target = positional[0] ?? '/';
|
|
441
|
+
const isUrl = /^https?:\/\//.test(target);
|
|
442
|
+
const strategy = flags.mobile && !flags.desktop ? 'mobile' : flags.desktop && !flags.mobile ? 'desktop' : 'both';
|
|
443
|
+
const args = { site_id: ctx.cfg.site, strategy, ...(isUrl ? { url: target } : { path: target, site: flags.live ? 'live' : 'preview' }), ...(flags.against ? { compare_url: String(flags.against) } : {}) };
|
|
444
|
+
say(`Testing${flags.against ? ' both pages' : ''} with PageSpeed Insights (a minute or two)...`);
|
|
445
|
+
const { json } = await tool(ctx.cfg, 'speed_website', args);
|
|
446
|
+
if (!json?.page) fail('No result came back.');
|
|
447
|
+
const outDir = join(ctx.dir, META, 'speed');
|
|
448
|
+
mkdirSync(outDir, { recursive: true });
|
|
449
|
+
const stamp = new Date().toISOString().replace(/[-:.]/g, '').slice(4, 18);
|
|
450
|
+
const base = (isUrl ? new URL(target).hostname + new URL(target).pathname : target).replace(/[^a-z0-9]+/gi, '-').replace(/^-|-$/g, '') || 'home';
|
|
451
|
+
const file = join(outDir, `${base}-${stamp}.json`);
|
|
452
|
+
writeFileSync(file, JSON.stringify(json, null, '\t'));
|
|
453
|
+
const n = (v, unit = '') => (v === null || v === undefined ? '—' : `${v}${unit}`);
|
|
454
|
+
const line = (r) => r.error ? ` ${r.strategy.padEnd(8)} ${r.error}` : ` ${r.strategy.padEnd(8)} perf ${n(r.scores.performance)} a11y ${n(r.scores.accessibility)} best ${n(r.scores.best_practices)} seo ${n(r.scores.seo)} LCP ${n(r.lab.lcp_ms, 'ms')} FCP ${n(r.lab.fcp_ms, 'ms')} TBT ${n(r.lab.tbt_ms, 'ms')} CLS ${n(r.lab.cls)} ${r.lab.total_bytes ? Math.round(r.lab.total_bytes / 1024) + ' KB' : '—'} in ${n(r.lab.requests)} requests${r.field ? ` field: LCP ${n(r.field.lcp_ms, 'ms')} INP ${n(r.field.inp_ms, 'ms')} CLS ${n(r.field.cls)} (${r.field.overall})` : ''}`;
|
|
455
|
+
say(`\n${json.target}`);
|
|
456
|
+
for (const r of json.page) say(line(r));
|
|
457
|
+
if (json.compare) { say(`\n${json.compare_url} (the page it is compared with)`); for (const r of json.compare) say(line(r)); }
|
|
458
|
+
for (const r of json.page) {
|
|
459
|
+
if (r.error) continue;
|
|
460
|
+
say(`\n ${r.strategy}: what to change`);
|
|
461
|
+
if (r.lcp_element) say(` largest paint: ${r.lcp_element.replace(/\s+/g, ' ').slice(0, 160)}`);
|
|
462
|
+
for (const o of r.opportunities.slice(0, 8)) {
|
|
463
|
+
say(` • ${o.title}${o.savings_ms ? ` (${o.savings_ms} ms)` : ''}${o.savings_kb ? ` (${o.savings_kb} KB)` : ''}`);
|
|
464
|
+
for (const it of o.items.slice(0, 4)) say(` ${it}`);
|
|
465
|
+
}
|
|
466
|
+
for (const d of r.diagnostics.slice(0, 8)) say(` · ${d}`);
|
|
467
|
+
}
|
|
468
|
+
say(`\nSaved to ${relative(process.cwd(), file)}. Full reports: ${json.page.filter((r) => !r.error).map((r) => r.report_url).join(' ')}`);
|
|
469
|
+
}
|
|
470
|
+
|
|
437
471
|
/** The website's redirects: list them, add one, remove one. They ship with the next publish. */
|
|
438
472
|
async function redirect(ctx) {
|
|
439
473
|
const sub = positional[0];
|
|
@@ -642,6 +676,8 @@ async function main() {
|
|
|
642
676
|
}
|
|
643
677
|
case 'measure':
|
|
644
678
|
return measure(config());
|
|
679
|
+
case 'speed':
|
|
680
|
+
return speed(config());
|
|
645
681
|
case 'redirect':
|
|
646
682
|
case 'redirects':
|
|
647
683
|
return redirect(config());
|
package/package.json
CHANGED