Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/vite-build-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Test Vite build
on:
pull_request:
branches:
- main
- main-labs
paths:
- '.github/workflows/vite-build-test.yml'
- 'package.json'
- 'yarn.lock'
- 'react-navigation/**'
- 'src/**'
- 'apps/**'
- 'FabricExample/**'
push:
branches:
- main
- main-labs
workflow_dispatch:

jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
WORKING_DIRECTORY: FabricExample
concurrency:
group: vite-build-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Node.js (version from .nvmrc)
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
cache-dependency-path: |
yarn.lock
react-navigation/yarn.lock
${{ env.WORKING_DIRECTORY }}/yarn.lock

- name: Install submodule dependencies
run: yarn submodules

- name: Install root node dependencies
run: yarn

- name: Build library
run: yarn prepare

- name: Install node dependencies
working-directory: ${{ env.WORKING_DIRECTORY }}
run: yarn

- name: Build Vite app
working-directory: ${{ env.WORKING_DIRECTORY }}
run: yarn build:web
3 changes: 3 additions & 0 deletions FabricExample/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ yarn-error.log
# testing
/coverage

# Vite
dist/

# Yarn
.yarn/*
!.yarn/patches
Expand Down
8 changes: 4 additions & 4 deletions FabricExample/e2e/e2e-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,18 @@ export async function getElementAttributes(
testLabel: string,
): Promise<ElementAttributes> {
const attrs = await element(by.label(testLabel)).getAttributes();

if ('elements' in attrs) {
throw new Error(
`Multiple elements (${attrs.elements.length}) found for label: "${testLabel}". `
`Multiple elements (${attrs.elements.length}) found for label: "${testLabel}". `,
);
}

return attrs as ElementAttributes;
}

/**
* Performs a coordinate-based tap on iOS to interact with an element that may be
* Performs a coordinate-based tap on iOS to interact with an element that may be
* obstructed by other UI layers, bypassing Detox's default visibility checks.
*/
export async function forceTapByLabeliOS(testLabel: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '../../e2e-utils';

/**
* Selects a tab bar item. On iOS, this uses a forced coordinate tap to
* Selects a tab bar item. On iOS, this uses a forced coordinate tap to
* ensure the tab is selected even if it is obstructed by the iOS 26 Liquid Glass lens.
*/
async function forceSelectTabByLabel(label: string) {
Expand Down
25 changes: 25 additions & 0 deletions FabricExample/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<style>
html,
body {
height: 100%;
}

#root {
display: flex;
height: 100%;
}
</style>
</head>
<body>
<div id="root"></div>
<script type="module" src="./index.js"></script>
</body>
</html>
8 changes: 7 additions & 1 deletion FabricExample/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { AppRegistry } from 'react-native';
import { AppRegistry, Platform } from 'react-native';
import App from './App';
import { name as appName } from './app.json';

AppRegistry.registerComponent(appName, () => App);

if (Platform.OS === 'web' && typeof document !== 'undefined') {
AppRegistry.runApplication(appName, {
rootTag: document.getElementById('root'),
});
}
10 changes: 9 additions & 1 deletion FabricExample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
"ios": "npx react-native run-ios",
"lint": "eslint .",
"start": "npx react-native start",
"web": "vite",
"build:web": "vite build",
"test": "jest",
"build-e2e-ios": "detox build --configuration ios.sim.release",
"build-e2e-android": "detox build --configuration android.emu.release",
Expand All @@ -25,12 +27,14 @@
"@react-navigation/stack": "link:../react-navigation/packages/stack/",
"nanoid": "^4.0.2",
"react": "19.2.3",
"react-dom": "19.2.3",
"react-native": "0.85.0",
"react-native-gesture-handler": "^2.31.1",
"react-native-reanimated": "~4.3.0",
"react-native-restart": "^0.0.27",
"react-native-safe-area-context": "5.6.0",
"react-native-screens": "link:../",
"react-native-web": "~0.21.2",
"react-native-worklets": "~0.8.1"
},
"resolutions": {
Expand All @@ -52,16 +56,20 @@
"@types/jest": "^29.5.13",
"@types/react": "^19.2.0",
"@types/react-test-renderer": "^19.1.0",
"@vitejs/plugin-react": "^5.0.0",
"babel-jest": "^29.6.3",
"babel-plugin-module-resolver": "^5.0.3",
"detox": "^20.45.1",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"patch-package": "^8.0.0",
"prettier": "2.8.8",
"react-native-builder-bob": "^0.41.0",
"react-test-renderer": "19.2.3",
"ts-jest": "^29.0.3",
"typescript": "5.0.4"
"typescript": "5.0.4",
"vite": "^7.1.1",
"vite-plugin-commonjs": "^0.10.4"
},
"engines": {
"node": ">= 22.11.0"
Expand Down
43 changes: 43 additions & 0 deletions FabricExample/vite.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { defineConfig, mergeConfig, transformWithEsbuild } from 'vite';

import config from 'react-native-builder-bob/vite-config';
import appPack from './package.json' with { type: 'json' };
import pack from '../package.json' with { type: 'json' };

// The code is in `../apps`, so dependencies can't be found there
// So we alias them to resolve to the ones in this package's node_modules
const dependencyAliases = Object.keys(appPack.dependencies)
.filter(name => name !== 'react-native' && name !== pack.name)
.map(name => [name, new URL(`./node_modules/${name}`, import.meta.url)]);

function appsJsAsJsx() {
return {
name: 'apps-js-as-jsx',
enforce: 'pre',
transform(code, id) {
if (id.endsWith('.js') && /\/apps\//.test(id)) {
return transformWithEsbuild(code, id, {
loader: 'jsx',
jsx: 'automatic',
});
}

return null;
},
};
}

export default defineConfig(env =>
mergeConfig(config(env), {
plugins: [appsJsAsJsx()],
resolve: {
alias: {
...Object.fromEntries(dependencyAliases),
[pack.name]: new URL('..', import.meta.url),
'@apps': new URL('../apps/src', import.meta.url),
'@assets': new URL('../apps/assets', import.meta.url),
},
dedupe: Object.keys(pack.peerDependencies),
},
}),
);
Loading