Skip to content

Update ts-bridge and Build Pipeline for React Native Packages #702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
georgewrmarshall opened this issue May 25, 2025 · 0 comments · Fixed by #704
Closed

Update ts-bridge and Build Pipeline for React Native Packages #702

georgewrmarshall opened this issue May 25, 2025 · 0 comments · Fixed by #704
Assignees

Comments

@georgewrmarshall
Copy link
Contributor

Background

Previously, the React Native packages (@metamask/design-system-react-native and @metamask/design-system-twrnc-preset) were using tsc directly for building instead of the monorepo's standard ts-bridge build system. This was due to a known issue with ts-bridge not properly handling React Native's index.js file which contains Flow code rather than plain JavaScript.

Root Cause: ts-bridge issue #72 - React Native's index.js file contains Flow code, which caused ts-bridge's import rewriting to fail when the file couldn't be parsed by cjs-module-lexer.

Resolution: This issue was fixed in ts-bridge PR #73 which handles export detection errors gracefully by leaving imports as-is when packages cannot be parsed.

Objectives

  1. Standardize Build System: Migrate React Native packages to use ts-bridge for consistency with the rest of the monorepo
  2. Update Package Configuration: Align package.json exports and scripts with other packages
  3. Simplify Build Pipeline: Remove custom build scripts and configurations
  4. Update Constraints: Remove React Native-specific exceptions from yarn constraints
  5. Improve Test Configuration: Update Jest configuration for better test handling

Changes Made

1. Package Configuration Updates

@metamask/design-system-react-native

  • ✅ Updated package.json to use ts-bridge build script
  • ✅ Standardized exports format to dual module (ESM/CJS) structure
  • ✅ Removed custom scripts/build.js file
  • ✅ Updated tsconfig.build.json for ts-bridge compatibility
  • ✅ Fixed TypeScript configuration to resolve React Native type conflicts

@metamask/design-system-twrnc-preset

  • ✅ Updated package.json to use ts-bridge build script
  • ✅ Standardized exports format to dual module (ESM/CJS) structure
  • ✅ Updated Jest configuration with passWithNoTests: true
  • ✅ Adjusted coverage thresholds to realistic levels

2. Build System Improvements

Before (using tsc):

{
  "scripts": {
    "build": "node scripts/build.js"
  }
}

After (using ts-bridge):

{
  "scripts": {
    "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references"
  }
}

3. Exports Standardization

Both packages now use the standard dual module format:

{
  "exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.mts",
        "default": "./dist/index.mjs"
      },
      "require": {
        "types": "./dist/index.d.cts",
        "default": "./dist/index.cjs"
      }
    }
  }
}

4. Yarn Constraints Cleanup

Removed React Native-specific exceptions from yarn.config.cjs:

  • ✅ Removed export validation exceptions
  • ✅ Removed test script exceptions
  • ✅ All packages now follow the same constraints

5. Preview Build Script Cleanup

Updated scripts/prepare-preview-builds.sh:

  • ✅ Removed React Native-specific TypeScript import handling
  • ✅ Simplified the build process since all packages now use the same build system

6. TypeScript Configuration

React Native Package (tsconfig.build.json):

{
  "extends": "../../tsconfig.packages.build.json",
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist",
    "rootDir": "./src",
    "jsx": "react-native",
    "types": ["react-native", "jest"],
    "skipLibCheck": true,
    "esModuleInterop": true,
    "moduleResolution": "Node16"
  },
  "references": [
    { "path": "../design-system-twrnc-preset/tsconfig.build.json" }
  ],
  "include": ["./src", "global.d.ts"]
}

7. Jest Configuration Improvements

TWRNC Preset (jest.config.js):

module.exports = merge(baseConfig, {
  displayName,
  passWithNoTests: true,
  coverageThreshold: {
    global: {
      branches: 75,
      functions: 70,
      lines: 84,
      statements: 84,
    },
  },
  // ... React Native specific configurations
});

Verification

Build Verification

# Individual package builds
yarn workspace @metamask/design-system-react-native build
yarn workspace @metamask/design-system-twrnc-preset build

# Full monorepo build
yarn build

# Test execution
yarn workspace @metamask/design-system-twrnc-preset test

Output Structure

Both packages now generate the correct dual module format:

dist/
├── index.cjs          # CommonJS bundle
├── index.d.cts        # CommonJS type definitions
├── index.mjs          # ES Module bundle
└── index.d.mts        # ES Module type definitions

Benefits

  1. Consistency: All packages now use the same build system and configuration patterns
  2. Maintainability: Reduced custom build scripts and configurations
  3. Type Safety: Improved TypeScript configuration and dual module support
  4. Developer Experience: Simplified build process and better error handling
  5. Future-Proof: Aligned with ts-bridge improvements and React Native compatibility

Dependencies

  • @ts-bridge/cli: ^0.6.3 (includes the React Native fix)
  • React Native type definitions properly configured
  • Updated yarn constraints validation

Testing

  • ✅ All packages build successfully with ts-bridge
  • ✅ Dual module outputs are generated correctly
  • ✅ Yarn constraints pass without exceptions
  • ✅ Tests run successfully with updated Jest configuration
  • ✅ Preview build script works without React Native-specific handling

Related Issues

Impact

This change brings the React Native packages in line with the rest of the monorepo's build system, eliminating technical debt and improving maintainability. The migration was made possible by the resolution of the underlying ts-bridge compatibility issue with React Native.

@georgewrmarshall georgewrmarshall self-assigned this May 25, 2025
georgewrmarshall added a commit that referenced this issue Jun 9, 2025
## **Description**

This PR updates the build pipeline for React Native packages to align
with the rest of the monorepo by leveraging the latest version of
ts-bridge (v0.6.3). This was previously blocked by [an
issue](ts-bridge/ts-bridge#72) with
ts-bridge's export detection for Flow files (specifically with React
Native), but [has been
fixed](ts-bridge/ts-bridge#73 ts-bridge
v0.6.3.

1. What is the reason for the change?
- Previously, React Native packages had a different build setup due to
ts-bridge's inability to handle Flow files
- This inconsistency made it harder to maintain the build pipeline
across the monorepo
- The recent fix in ts-bridge now allows us to standardize our build
approach

2. What is the improvement/solution?
- Updates ts-bridge to v0.6.3 which includes the Flow file handling fix
- Aligns the build configuration for React Native packages with other
packages
   - Implements proper ESM/CJS dual package hazard handling
- Updates file extensions to properly support both ESM (.mjs/.mts) and
CJS (.cjs/.cts)
   - Standardizes test configurations across packages

## **Related issues**

Fixes: #702

## **Manual testing steps**

1. Clean install dependencies: `yarn install`
2. Build all packages: `yarn build`
3. Verify that React Native packages build successfully
4. Run tests: `yarn test`
5. Verify that imports work correctly in both ESM and CJS environments

*Test preview packages in mobile:*

1. Go to [this
PR](https://github.com/MetaMask/metamask-mobile/pull/16103/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519R180-R182)
2. Run the app.
4. Confirm that DSRN components are functioning on the login page using
the [published preview from this
PR](#704 (comment)).

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs)
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant