build - saltict/Demo-Docs GitHub Wiki
This document describes the build system, compilation process, and output generation for the SubWallet Services SDK.
- 📋 Overview
- 🏗️ Build System
- ⚙️ Build Configuration
- 📦 Build Outputs
- 🔄 Build Pipeline
- 🛠️ Advanced Build Options
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.
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 |
%%{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
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
}
}
}
}
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',
},
},
});
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"
]
}
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
// 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"
}
};
}
# 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 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 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
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"
}
}
// 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}`);
}
}
}
}
// 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
})
]
});
}
// 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...');
}
}
]
}
}
});
// 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));
}
// 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
}
}
});
# Clear TypeScript cache
rm -rf node_modules/.cache/typescript
rm -rf dist/
# Rebuild with clean slate
nx reset
nx build subwallet-services-sdk
// 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}`);
}
}
}
# 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:
- Set up Testing
- Configure Development Workflow
- Review Deployment Process
Navigation: ← Development Setup | Development Overview | Testing →