Skip to content

Latest commit

 

History

History
277 lines (228 loc) · 7.24 KB

File metadata and controls

277 lines (228 loc) · 7.24 KB

Package Structure Guidelines

This document describes the standard structure and conventions for packages in this monorepo.

Standard Package Structure

TypeScript/JavaScript Packages

All TypeScript/JavaScript packages should follow this structure:

packages/package-name/
├── src/
│   ├── index.ts                      # Main entry point
│   ├── launcher.ts                   # Launcher (if service)
│   ├── service.ts                    # Service (if service)
│   ├── types.ts                      # Type definitions
│   └── utils/                        # Utility functions
│       └── logger.ts
├── test/
│   ├── launcher.spec.ts              # Launcher tests
│   ├── service.spec.ts               # Service tests
│   └── utils.spec.ts                 # Utility tests
├── dist/
│   ├── esm/                          # ESM build output
│   │   ├── index.js
│   │   └── index.d.ts
│   └── cjs/                          # CJS build output
│       ├── index.js
│       └── index.d.ts
├── package.json                      # Package manifest
├── tsconfig.json                     # TypeScript config (extends base)
├── tsconfig.cjs.json                 # TypeScript CJS config
├── vitest.config.ts                  # Vitest config
└── README.md                         # Package documentation

Rust/Tauri Plugin Packages

Tauri plugin packages follow a different structure:

packages/tauri-plugin/
├── src/
│   ├── lib.rs                        # Plugin entry point
│   ├── commands.rs                   # Tauri command implementations
│   ├── models.rs                     # Data models
│   ├── error.rs                      # Error types
│   ├── mock_store.rs                 # Mock storage implementation
│   ├── desktop.rs                    # Desktop-specific code
│   └── mobile.rs                     # Mobile-specific code
├── guest-js/                         # Frontend JavaScript/TypeScript
│   ├── index.ts                      # Frontend API implementation
│   └── index.d.ts                    # TypeScript definitions
├── permissions/                      # Tauri v2 permissions
│   ├── default.toml                  # Default permissions
│   └── autogenerated/                # Auto-generated permission files
├── build.rs                          # Build script
├── Cargo.toml                        # Rust crate manifest
├── package.json                      # NPM package manifest (for frontend)
├── tsconfig.json                     # TypeScript config for frontend
└── README.md                         # Package documentation

Package Naming Conventions

Service Packages

All packages use the @wdio/ scope:

  • @wdio/electron-service - Electron WDIO service
  • @wdio/tauri-service - Tauri WDIO service
  • @wdio/electron-cdp-bridge - Chrome DevTools Protocol bridge
  • @wdio/native-utils - Cross-platform utilities
  • @wdio/native-types - Shared TypeScript type definitions
  • @wdio/native-spy - Spy utilities for mocking
  • @wdio/tauri-plugin - Tauri v2 plugin (Rust + JS)
  • @wdio/bundler - Build tooling

package.json Template

{
  "name": "@wdio/package-name",
  "version": "1.0.0",
  "type": "module",
  "description": "Package description",
  "main": "./dist/cjs/index.js",
  "module": "./dist/esm/index.js",
  "types": "./dist/esm/index.d.ts",
  "exports": {
    ".": {
      "import": {
        "types": "./dist/esm/index.d.ts",
        "default": "./dist/esm/index.js"
      },
      "require": {
        "types": "./dist/cjs/index.d.ts",
        "default": "./dist/cjs/index.js"
      }
    }
  },
  "engines": {
    "node": "^18.12.0 || ^20.0.0"
  },
  "scripts": {
    "build": "pnpm build:esm && pnpm build:cjs",
    "build:esm": "tsc -p tsconfig.json",
    "build:cjs": "tsc -p tsconfig.cjs.json",
    "test": "vitest run",
    "test:coverage": "vitest run --coverage",
    "lint": "biome check .",
    "typecheck": "tsc --noEmit",
    "clean": "shx rm -rf dist coverage .turbo"
  },
  "dependencies": {},
  "devDependencies": {
    "@types/node": "catalog:default",
    "@vitest/coverage-v8": "catalog:default",
    "typescript": "catalog:default",
    "vitest": "catalog:default"
  },
  "peerDependencies": {
    "webdriverio": "^9.0.0"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/webdriverio/desktop-mobile.git",
    "directory": "packages/package-name"
  },
  "license": "MIT"
}

TypeScript Configuration

Each package should have two TypeScript configurations:

tsconfig.json (ESM)

{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist/esm",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "test"]
}

tsconfig.cjs.json (CJS)

{
  "extends": "../../tsconfig.base.cjs.json",
  "compilerOptions": {
    "outDir": "./dist/cjs",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "test"]
}

Vitest Configuration

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globals: true,
    environment: 'node',
    include: ['test/**/*.spec.ts'],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      thresholds: {
        lines: 80,
        functions: 80,
        branches: 80,
        statements: 80,
      },
    },
  },
});

Build Scripts

Packages should build to both ESM and CJS formats:

# Build both formats
pnpm build

# Build ESM only
pnpm build:esm

# Build CJS only
pnpm build:cjs

Testing

All packages must maintain 80%+ test coverage:

# Run tests
pnpm test

# Run tests with coverage
pnpm test:coverage

Dependencies

Use Workspace Protocol

For internal dependencies, use the workspace: protocol:

{
  "dependencies": {
    "@wdio/native-utils": "workspace:*"
  }
}

Use Catalog for Common Dependencies

For common external dependencies, use the catalog reference:

{
  "devDependencies": {
    "typescript": "catalog:default",
    "vitest": "catalog:default"
  }
}

README Template

Each package should have a comprehensive README with:

  1. Description - What the package does
  2. Installation - How to install
  3. Usage - Basic usage examples
  4. API - API documentation
  5. Configuration - Configuration options
  6. Examples - Code examples
  7. Contributing - Contribution guidelines
  8. License - License information

Publishing

Packages are published from the monorepo using Turborepo:

# Publish all packages
pnpm turbo release

Best Practices

  1. Keep packages focused - Each package should have a single responsibility
  2. Minimize dependencies - Only add necessary dependencies
  3. Write comprehensive tests - Maintain 80%+ coverage
  4. Document public APIs - Use JSDoc comments
  5. Follow TypeScript strict mode - Enable strict type checking
  6. Use semantic versioning - Follow semver for versions
  7. Avoid breaking changes - Maintain backward compatibility when possible