Files
2025-11-29 17:56:31 +08:00

11 KiB
Raw Permalink Blame History

name, description
name description
specweave-docs-preview:build Build static documentation site for deployment. Generates production-ready HTML/CSS/JS files optimized for static hosting.

Documentation Build Command

Build a production-ready static documentation site from your SpecWeave living documentation.

Your Task

Execute the following workflow to build the static documentation site:

Step 1: Load the Build Utilities

import { buildStaticSite, isSetupNeeded } from '../../../src/utils/docs-preview/index.js';
import * as fs from 'fs-extra';
import * as path from 'path';

Step 2: Check Prerequisites

const projectRoot = process.cwd();

// Check if docs preview is configured
const configPath = path.join(projectRoot, '.specweave', 'config.json');
let config: any = {};
if (fs.existsSync(configPath)) {
  config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
}

const docsConfig = config.documentation?.preview || {};

console.log('\n📦 Building Documentation Site...\n');

// Check if Docusaurus is installed
const setupNeeded = await isSetupNeeded(projectRoot);

if (setupNeeded) {
  console.error('❌ Docusaurus not installed\n');
  console.log('💡 Solution:');
  console.log('   Run: /specweave-docs-preview:preview');
  console.log('   This will install Docusaurus first\n');
  process.exit(1);
}

Step 3: Build the Static Site

try {
  console.log('  Building production site...');
  console.log('   • Compiling React components');
  console.log('   • Optimizing assets');
  console.log('   • Generating static HTML\n');

  await buildStaticSite(projectRoot);

  const buildPath = path.join(projectRoot, '.specweave', 'docs-site-internal', 'build');
  const buildStats = await getBuildStats(buildPath);

  console.log('\n✅ Build Complete!\n');
  console.log('📊 Build Statistics:');
  console.log(`   • Pages: ${buildStats.pages} HTML files`);
  console.log(`   • Size: ${buildStats.totalSize}`);
  console.log(`   • Location: ${buildPath}\n`);

  console.log('🚀 Deployment Options:\n');
  console.log('1⃣  Netlify:');
  console.log('   cd .specweave/docs-site-internal');
  console.log('   npx netlify deploy --dir=build --prod\n');

  console.log('2⃣  Vercel:');
  console.log('   cd .specweave/docs-site-internal');
  console.log('   npx vercel --prod\n');

  console.log('3⃣  GitHub Pages:');
  console.log('   cp -r build/* docs/');
  console.log('   git add docs/ && git commit -m "docs: update"');
  console.log('   git push\n');

  console.log('4⃣  Static Server (local test):');
  console.log('   npx serve build/\n');

  console.log('5⃣  Your own server:');
  console.log('   scp -r build/* user@server:/var/www/docs/\n');

} catch (error: any) {
  console.error('\n❌ Build Failed\n');
  console.error(`Error: ${error.message}\n`);

  console.log('💡 Troubleshooting:');
  console.log('   • Check all markdown files have valid frontmatter');
  console.log('   • Ensure no broken internal links');
  console.log('   • Run preview first to catch errors: /specweave-docs-preview:preview');
  console.log('   • Check build logs above for specific errors\n');

  process.exit(1);
}

Step 4: Helper Function - Get Build Statistics

async function getBuildStats(buildPath: string): Promise<{
  pages: number;
  totalSize: string;
}> {
  let pages = 0;
  let totalBytes = 0;

  async function walk(dir: string) {
    const files = await fs.readdir(dir);
    for (const file of files) {
      const filePath = path.join(dir, file);
      const stats = await fs.stat(filePath);
      if (stats.isDirectory()) {
        await walk(filePath);
      } else {
        totalBytes += stats.size;
        if (file.endsWith('.html')) {
          pages++;
        }
      }
    }
  }

  await walk(buildPath);

  const totalMB = (totalBytes / 1024 / 1024).toFixed(2);
  return {
    pages,
    totalSize: `${totalMB} MB`
  };
}

What Gets Built

Output Directory Structure

.specweave/docs-site-internal/build/
├── index.html                    ← Landing page
├── docs/
│   ├── strategy/
│   │   ├── prd-001/
│   │   │   └── index.html
│   │   └── okrs/
│   │       └── index.html
│   ├── specs/
│   │   ├── spec-001-auth/
│   │   │   └── index.html
│   │   └── spec-002-payments/
│   │       └── index.html
│   └── architecture/
│       ├── hld-system/
│       │   └── index.html
│       └── adr/
│           └── 0001-database-choice/
│               └── index.html
├── assets/
│   ├── css/
│   │   └── styles.[hash].css    ← Optimized CSS
│   ├── js/
│   │   └── runtime.[hash].js    ← React runtime
│   └── images/                  ← Optimized images
└── sitemap.xml                  ← Search engine sitemap

Build Optimizations

  1. Code Splitting: React chunks loaded on demand
  2. Asset Optimization: CSS/JS minified and compressed
  3. Image Optimization: Auto-resized and compressed
  4. Static HTML: Pre-rendered pages for fast loading
  5. Search Index: Pre-generated search index
  6. Sitemap: Auto-generated for SEO

Deployment Examples

Option 1: CLI

cd .specweave/docs-site-internal
npx netlify deploy --dir=build --prod

Option 2: Drag & Drop

  1. Go to https://app.netlify.com/drop
  2. Drag .specweave/docs-site-internal/build/ folder
  3. Done! Get instant URL

Option 3: Git Integration

  1. Create netlify.toml:
    [build]
      base = ".specweave/docs-site-internal"
      publish = "build"
      command = "npm run build"
    
  2. Connect GitHub repo
  3. Auto-deploy on push

Vercel

cd .specweave/docs-site-internal
npx vercel --prod

GitHub Pages

Option 1: docs/ folder

# 1. Copy build to docs/
cp -r .specweave/docs-site-internal/build/* docs/

# 2. Enable GitHub Pages
# Go to Settings → Pages → Source: main branch /docs folder

# 3. Push
git add docs/
git commit -m "docs: update documentation site"
git push

Option 2: gh-pages branch

# 1. Install gh-pages
npm install -g gh-pages

# 2. Deploy
gh-pages -d .specweave/docs-site-internal/build

AWS S3 + CloudFront

# 1. Sync to S3
aws s3 sync .specweave/docs-site-internal/build/ s3://your-bucket/ \
  --delete \
  --cache-control "max-age=31536000,public"

# 2. Invalidate CloudFront
aws cloudfront create-invalidation \
  --distribution-id YOUR_DIST_ID \
  --paths "/*"

Docker + Nginx

Dockerfile:

FROM nginx:alpine
COPY .specweave/docs-site-internal/build/ /usr/share/nginx/html/
EXPOSE 80

Build and run:

docker build -t docs .
docker run -p 80:80 docs

Your Own Server

Nginx config:

server {
    listen 80;
    server_name docs.example.com;
    root /var/www/docs;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Deploy:

scp -r .specweave/docs-site-internal/build/* user@server:/var/www/docs/

Testing Before Deployment

Local Testing with Serve

# 1. Install serve
npm install -g serve

# 2. Serve build folder
cd .specweave/docs-site-internal
serve build/

# 3. Open browser
# Visit: http://localhost:3000

Check Lighthouse Scores

# 1. Install lighthouse
npm install -g lighthouse

# 2. Run audit
lighthouse http://localhost:3000 \
  --view \
  --output html

# Expected scores:
# Performance: 100
# Accessibility: 100
# Best Practices: 100
# SEO: 100

Expected Output

Successful Build:

📦 Building Documentation Site...

  Building production site...
   • Compiling React components
   • Optimizing assets
   • Generating static HTML

[==================================] 100%

✅ Build Complete!

📊 Build Statistics:
   • Pages: 42 HTML files
   • Size: 3.2 MB
   • Location: /project/.specweave/docs-site-internal/build/

🚀 Deployment Options:

1⃣  Netlify:
   cd .specweave/docs-site-internal
   npx netlify deploy --dir=build --prod

2⃣  Vercel:
   cd .specweave/docs-site-internal
   npx vercel --prod

3⃣  GitHub Pages:
   cp -r build/* docs/
   git add docs/ && git commit -m "docs: update"
   git push

4⃣  Static Server (local test):
   npx serve build/

5⃣  Your own server:
   scp -r build/* user@server:/var/www/docs/

Common Build Errors

Invalid Frontmatter

Error: Invalid frontmatter in file: spec-001.md

Fix:

---
title: User Authentication
sidebar_position: 1
---

Content here...
Error: Broken link in file: architecture/hld.md
Link: ../specs/missing-file.md

Fix: Update or remove broken links

Missing Dependencies

Error: Module not found: 'react'

Fix:

cd .specweave/docs-site-internal
npm install

Build vs Preview

Aspect Preview (/specweave-docs-preview:preview) Build (/specweave-docs-preview:build)
Purpose Development, hot reload Production deployment
Speed Instant start 5-10 seconds build
Output Dev server Static files
Hot Reload Yes No
Optimization No Yes (minified, compressed)
Search Works Pre-generated index
Use When Editing docs Deploying to server

Best Practices

1. Build Before Every Deployment

Always build fresh before deploying:

/specweave-docs-preview:build
# Then deploy

2. Test Build Locally

/specweave-docs-preview:build
cd .specweave/docs-site-internal
npx serve build/
# Visit http://localhost:3000 and test

3. Check All Pages

  • Click through every page
  • Test search functionality
  • Verify all links work
  • Check mobile responsiveness

4. Optimize Images

Before building, optimize images:

# Install sharp-cli
npm install -g sharp-cli

# Optimize images
sharp -i docs/images/*.png -o docs/images/optimized/ -q 80

5. Update Sitemap

The sitemap is auto-generated, but verify it:

cat .specweave/docs-site-internal/build/sitemap.xml

Integration with CI/CD

GitHub Actions

.github/workflows/docs.yml:

name: Deploy Docs

on:
  push:
    branches: [main]
    paths:
      - '.specweave/docs/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install SpecWeave
        run: npm install -g specweave

      - name: Build Docs
        run: specweave docs build

      - name: Deploy to Netlify
        run: |
          cd .specweave/docs-site-internal
          npx netlify deploy --dir=build --prod
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_TOKEN }}

See Also