build - saltict/Demo-Docs GitHub Wiki

Build Process

This document describes the build system, compilation process, and output generation for the SubWallet Services SDK.

Quick Navigation

Overview

The SubWallet Services SDK uses a modern build system based on Nx, Vite, and TypeScript to create optimized, tree-shakeable library bundles suitable for both Node.js and browser environments.

Build System

Technology Stack

Tool Purpose Version Configuration
Nx Build orchestration Latest project.json
Vite Build engine Latest vite.config.ts
TypeScript Type compilation 5.x tsconfig.json
ESLint Code quality Latest eslint.config.cjs
Jest Testing Latest jest.config.ts

Build Architecture

%%{init: {'theme':'dark'}}%%
graph TB
    Source[Source Code] --> TSCheck[TypeScript Check]
    Source --> Lint[ESLint Check]
    TSCheck --> Compile[Vite Compilation]
    Lint --> Compile
    
    Compile --> Bundle[Bundle Generation]
    Bundle --> Types[Type Declarations]
    Bundle --> Maps[Source Maps]
    Bundle --> Package[Package.json]
    
    Types --> Output[dist/ Output]
    Maps --> Output
    Package --> Output
    
    Output --> Validate[Build Validation]
    Validate --> Complete[Build Complete]
    
    style Source fill:#2d3748,stroke:#4a5568,color:#fff
    style TSCheck fill:#3b82f6,stroke:#2563eb,color:#fff
    style Lint fill:#3b82f6,stroke:#2563eb,color:#fff
    style Compile fill:#10b981,stroke:#059669,color:#fff
    style Bundle fill:#8b5cf6,stroke:#7c3aed,color:#fff
    style Types fill:#8b5cf6,stroke:#7c3aed,color:#fff
    style Maps fill:#8b5cf6,stroke:#7c3aed,color:#fff
    style Package fill:#8b5cf6,stroke:#7c3aed,color:#fff
    style Output fill:#fbbf24,stroke:#f59e0b,color:#000
    style Validate fill:#ef4444,stroke:#dc2626,color:#fff
    style Complete fill:#065f46,stroke:#047857,color:#fff
Loading

Build Configuration

Nx Project Configuration

File: libs/subwallet-services-sdk/project.json

{
  "name": "subwallet-services-sdk",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "libs/subwallet-services-sdk/src",
  "projectType": "library",
  "tags": [],
  "targets": {
    "build": {
      "executor": "@nx/vite:build",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/libs/subwallet-services-sdk"
      }
    },
    "lint": {
      "executor": "@nx/eslint:eslint",
      "outputs": ["{options.outputFile}"],
      "options": {
        "lintFilePatterns": ["libs/subwallet-services-sdk/**/*.ts"]
      }
    },
    "test": {
      "executor": "@nx/jest:jest",
      "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
      "options": {
        "jestConfig": "libs/subwallet-services-sdk/jest.config.ts",
        "passWithNoTests": true
      }
    }
  }
}

Vite Configuration

File: libs/subwallet-services-sdk/vite.config.ts

import { defineConfig } from 'vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import dts from 'vite-plugin-dts';

export default defineConfig({
  root: __dirname,
  cacheDir: '../../node_modules/.vite/libs/subwallet-services-sdk',

  plugins: [
    nxViteTsPaths(),
    dts({
      entryRoot: 'src',
      tsConfigFilePath: './tsconfig.lib.json',
      skipDiagnostics: true,
    }),
  ],

  build: {
    outDir: '../../dist/libs/subwallet-services-sdk',
    reportCompressedSize: true,
    commonjsOptions: {
      transformMixedEsModules: true,
    },
    lib: {
      entry: 'src/index.ts',
      name: 'subwallet-services-sdk',
      fileName: 'index',
      formats: ['es', 'cjs'],
    },
    rollupOptions: {
      external: [
        // External dependencies that should not be bundled
        '@polkadot/api',
        '@polkadot/types',
        'axios',
        'lodash',
        'moment'
      ],
      output: {
        globals: {
          '@polkadot/api': 'PolkadotApi',
          '@polkadot/types': 'PolkadotTypes',
          'axios': 'axios',
          'lodash': '_',
          'moment': 'moment'
        }
      }
    },
  },

  test: {
    globals: true,
    cache: {
      dir: '../../node_modules/.vitest',
    },
    environment: 'node',
    include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
    reporters: ['default'],
    coverage: {
      reportsDirectory: '../../coverage/libs/subwallet-services-sdk',
      provider: 'v8',
    },
  },
});

TypeScript Configuration

File: libs/subwallet-services-sdk/tsconfig.lib.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "declaration": true,
    "types": ["node"]
  },
  "include": ["src/**/*.ts"],
  "exclude": [
    "jest.config.ts",
    "src/**/*.spec.ts",
    "src/**/*.test.ts"
  ]
}

Build Outputs

Directory Structure

dist/libs/subwallet-services-sdk/
├── index.js                    # ES Module bundle
├── index.cjs                   # CommonJS bundle  
├── index.d.ts                  # TypeScript declarations
├── index.js.map                # Source map for ES module
├── index.cjs.map               # Source map for CommonJS
├── package.json                # Generated package.json
├── README.md                   # Documentation
├── lib/                        # Internal library modules
│   ├── subwallet-services-sdk.js
│   ├── subwallet-services-sdk.d.ts
│   └── subwallet-services-sdk.js.map
├── services/                   # Service implementations
│   ├── price-history.js
│   ├── price-history.d.ts
│   ├── balance-detection.js
│   ├── balance-detection.d.ts
│   ├── xcm.js
│   ├── xcm.d.ts
│   ├── cardano.js
│   ├── cardano.d.ts
│   └── swap.js
├── types/                      # Type definitions
│   ├── index.d.ts
│   ├── interfaces.d.ts
│   └── common.d.ts
└── core/                       # Core utilities
    ├── http-client.js
    ├── http-client.d.ts
    └── constants.js

Package.json Generation

// File: scripts/generate-package-json.ts
export function generatePackageJson(sourcePackage: any): any {
  return {
    name: sourcePackage.name,
    version: sourcePackage.version,
    description: "SubWallet Services SDK - Comprehensive library for blockchain services",
    main: "./index.cjs",
    module: "./index.js",
    types: "./index.d.ts",
    exports: {
      ".": {
        "import": "./index.js",
        "require": "./index.cjs",
        "types": "./index.d.ts"
      }
    },
    files: [
      "index.js",
      "index.cjs",
      "index.d.ts",
      "lib/**/*",
      "services/**/*",
      "types/**/*",
      "core/**/*"
    ],
    keywords: [
      "blockchain",
      "wallet",
      "polkadot",
      "cardano",
      "defi",
      "xcm",
      "substrate"
    ],
    author: "SubWallet Team",
    license: "MIT",
    repository: {
      type: "git",
      url: "https://github.com/Koniverse/SubWallet-Extension"
    },
    peerDependencies: {
      "@polkadot/api": "^10.0.0",
      "axios": "^1.0.0"
    }
  };
}

Build Pipeline

Build Commands

Development Build

# Quick development build with type checking
nx build subwallet-services-sdk

# Build with watch mode for development
nx build subwallet-services-sdk --watch

# Build with detailed output
nx build subwallet-services-sdk --verbose

Production Build

# Production build with optimizations
NODE_ENV=production nx build subwallet-services-sdk

# Build with bundle analysis
nx build subwallet-services-sdk --analyze

# Build with size reporting
nx build subwallet-services-sdk --report-compressed-size

Build All Libraries

# Build all libraries in dependency order
nx run-many --target=build --all

# Build with parallel execution
nx run-many --target=build --all --parallel=3

# Build specific libraries
nx run-many --target=build --projects=subwallet-services-sdk,cardano,xcm

Build Script Integration

File: package.json (workspace root)

{
  "scripts": {
    "build": "nx run-many --target=build --all",
    "build:sdk": "nx build subwallet-services-sdk",
    "build:prod": "NODE_ENV=production nx run-many --target=build --all",
    "build:watch": "nx build subwallet-services-sdk --watch",
    "build:analyze": "nx build subwallet-services-sdk --analyze"
  }
}

Automated Build Pipeline

// File: scripts/build-pipeline.ts
export class BuildPipeline {
  async execute(): Promise<void> {
    console.log('🚀 Starting SubWallet Services SDK build pipeline...');
    
    try {
      // Step 1: Pre-build validation
      await this.validateEnvironment();
      await this.validateDependencies();
      
      // Step 2: Code quality checks
      await this.runLinting();
      await this.runTypeChecking();
      
      // Step 3: Testing
      await this.runTests();
      
      // Step 4: Build
      await this.runBuild();
      
      // Step 5: Post-build validation
      await this.validateBuildOutputs();
      await this.generateBuildReport();
      
      console.log('✅ Build pipeline completed successfully!');
    } catch (error) {
      console.error('❌ Build pipeline failed:', error);
      process.exit(1);
    }
  }

  private async validateEnvironment(): Promise<void> {
    const nodeVersion = process.version;
    const expectedMajor = 18;
    
    if (!nodeVersion.startsWith(`v${expectedMajor}`)) {
      throw new Error(`Node.js ${expectedMajor} required, got ${nodeVersion}`);
    }
  }

  private async runBuild(): Promise<void> {
    const { spawn } = await import('child_process');
    
    return new Promise((resolve, reject) => {
      const buildProcess = spawn('nx', ['build', 'subwallet-services-sdk'], {
        stdio: 'inherit'
      });
      
      buildProcess.on('close', (code) => {
        if (code === 0) {
          resolve();
        } else {
          reject(new Error(`Build failed with exit code ${code}`));
        }
      });
    });
  }

  private async validateBuildOutputs(): Promise<void> {
    const fs = await import('fs/promises');
    const path = await import('path');
    
    const distPath = 'dist/libs/subwallet-services-sdk';
    const requiredFiles = ['index.js', 'index.cjs', 'index.d.ts', 'package.json'];
    
    for (const file of requiredFiles) {
      const filePath = path.join(distPath, file);
      try {
        await fs.access(filePath);
      } catch {
        throw new Error(`Required build output missing: ${file}`);
      }
    }
  }
}

Advanced Build Options

Bundle Analysis

// File: scripts/analyze-bundle.ts
import { build } from 'vite';
import { visualizer } from 'rollup-plugin-visualizer';

export async function analyzeBundleSize(): Promise<void> {
  await build({
    plugins: [
      visualizer({
        filename: 'dist/bundle-analysis.html',
        open: true,
        gzipSize: true,
        brotliSize: true
      })
    ]
  });
}

Custom Build Hooks

// File: vite.config.ts (extended)
import { defineConfig } from 'vite';

export default defineConfig({
  // ... other config
  
  build: {
    // ... other build options
    
    rollupOptions: {
      plugins: [
        {
          name: 'custom-build-hooks',
          buildStart() {
            console.log('🏗️ Build started...');
          },
          generateBundle() {
            console.log('📦 Generating bundle...');
          },
          writeBundle() {
            console.log('✍️ Writing bundle to disk...');
          }
        }
      ]
    }
  }
});

Environment-Specific Builds

// File: scripts/build-environments.ts
export async function buildForEnvironment(env: string): Promise<void> {
  const configs = {
    development: {
      minify: false,
      sourcemap: true,
      target: 'esnext'
    },
    staging: {
      minify: true,
      sourcemap: true,
      target: 'es2020'
    },
    production: {
      minify: true,
      sourcemap: false,
      target: 'es2018'
    }
  };

  const config = configs[env as keyof typeof configs];
  if (!config) {
    throw new Error(`Unknown environment: ${env}`);
  }

  // Apply environment-specific build configuration
  process.env.VITE_BUILD_ENV = env;
  await import('vite').then(({ build }) => build(config));
}

Build Performance Optimization

// File: vite.config.ts (performance optimized)
export default defineConfig({
  build: {
    // Enable parallel processing
    rollupOptions: {
      maxParallelFileOps: 4,
    },
    
    // Optimize chunk splitting
    chunkSizeWarningLimit: 1000,
    
    // Enable compression
    reportCompressedSize: true,
    
    // Optimize dependencies
    commonjsOptions: {
      include: [/node_modules/],
      transformMixedEsModules: true
    }
  },
  
  // Optimize dev server
  server: {
    fs: {
      cachedChecks: false
    }
  }
});

Build Troubleshooting

Common Issues

Type Generation Errors

# Clear TypeScript cache
rm -rf node_modules/.cache/typescript
rm -rf dist/

# Rebuild with clean slate
nx reset
nx build subwallet-services-sdk

Bundle Size Issues

// Analyze what's in your bundle
import { Bundle } from 'rollup';

export function analyzeBundleContents(bundle: Bundle): void {
  for (const [fileName, chunk] of Object.entries(bundle)) {
    if (chunk.type === 'chunk') {
      console.log(`Chunk: ${fileName}`);
      console.log(`Size: ${chunk.code.length} bytes`);
      console.log(`Modules: ${Object.keys(chunk.modules).length}`);
    }
  }
}

Dependency Resolution

# Check for duplicate dependencies
nx dep-graph

# Verify peer dependencies
npm ls --depth=0

# Check for missing dependencies
nx build subwallet-services-sdk --verbose 2>&1 | grep "missing"

Next Steps:


Navigation: ← Development Setup | Development Overview | Testing →

⚠️ **GitHub.com Fallback** ⚠️