Skip to content

Monorepo support: tsconfig resolution needs environment-based configuration #131

@shogochiai

Description

@shogochiai

Monorepo support: tsconfig resolution needs environment-based configuration

Summary

scrypt-cli currently fails to compile contracts in monorepo environments due to hardcoded assumptions about project structure. The tool generates a default tsconfig-scryptTS.json with include: ["src/contracts/**/*.ts"], which doesn't work for monorepo layouts where contracts are distributed across multiple packages.

Current Behavior vs Expected Behavior

Current:

# In monorepo root with contracts at packages/*/src/contracts/
$ npx scrypt-cli compile
# Error: No inputs were found in config file
# (generates tsconfig looking for "./src/contracts/**/*.ts")

Expected:

# Should detect monorepo and use appropriate patterns
$ SCRYPT_CONTRACT_PATTERNS="packages/*/src/contracts/**/*.ts" npx scrypt-cli compile
# Success: compiles all contracts across packages

Minimal Reproduction

# 1. Create a monorepo
mkdir scrypt-mono && cd scrypt-mono
cat > package.json << EOF
{
  "name": "scrypt-mono",
  "workspaces": ["packages/*"]
}
EOF

# 2. Add a package with contract
mkdir -p packages/my-contracts/src/contracts
cat > packages/my-contracts/src/contracts/Test.ts << EOF
import { SmartContract, method, prop, assert } from 'scrypt-ts'

export class Test extends SmartContract {
    @prop() value: bigint
    
    constructor(value: bigint) {
        super(...arguments)
        this.value = value
    }
    
    @method()
    public unlock(x: bigint) {
        assert(this.value === x)
    }
}
EOF

# 3. Install dependencies
npm init -w packages/my-contracts -y
npm install
npm install -w packages/my-contracts scrypt-ts

# 4. Try to compile from root (fails)
npx scrypt-cli compile

# 5. Must cd to package directory (works)
cd packages/my-contracts
npx scrypt-cli compile

Root Cause

The issue occurs because:

  1. scrypt-cli generates tsconfig relative to current working directory
  2. The generated tsconfig always uses include: ["src/contracts/**/*.ts"]
  3. No detection or configuration for monorepo structures

Proposed Solution

Phase 1: Environment Variable Support (Non-breaking)

Add support for SCRYPT_CONTRACT_PATTERNS environment variable:

// In tsconfig generation logic
function generateDefaultTsconfig(cwd) {
  // Detect if we're in a monorepo
  const pkg = require(path.join(cwd, 'package.json'));
  const isMonorepo = !!(pkg.workspaces || existsSync('lerna.json') || existsSync('pnpm-workspace.yaml'));
  
  if (isMonorepo) {
    const patterns = process.env.SCRYPT_CONTRACT_PATTERNS;
    if (!patterns) {
      throw new Error(
        'Monorepo detected. Please set SCRYPT_CONTRACT_PATTERNS environment variable.\n' +
        'Example: export SCRYPT_CONTRACT_PATTERNS="packages/*/src/contracts/**/*.ts"'
      );
    }
    return {
      ...defaultOptions,
      include: patterns.split(',')
    };
  }
  
  // Keep existing behavior for non-monorepo
  return {
    ...defaultOptions,
    include: ["src/contracts/**/*.ts"]
  };
}

Usage

# In .env or shell profile
export SCRYPT_CONTRACT_PATTERNS="packages/*/src/contracts/**/*.ts,apps/*/contracts/**/*.ts"

# Now works from monorepo root
npx scrypt-cli compile

Benefits

  1. Zero breaking changes - Existing projects continue to work
  2. Explicit configuration - Users control their contract locations
  3. Clear error messages - Guides users when configuration is needed
  4. Flexible - Supports any monorepo structure

Alternative Considered

Auto-detection of contract locations was considered but rejected because:

  • Too many edge cases and conventions
  • Performance impact of filesystem scanning
  • Explicit configuration is clearer and more predictable

Next Steps

If this approach is acceptable, I can submit a PR with:

  • Implementation of environment variable support
  • Detection logic for common monorepo markers
  • Documentation updates
  • Tests for monorepo scenarios

Would you be open to this solution? Happy to discuss alternative approaches or implementation details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions