Skip to content

Commit 76c64c0

Browse files
authored
feat: gluestack nativewind (#128)
* feat: gluestack nativewind init commit * fix: metro runs and tests * fix: app builds without rebuild in wsl * docs: update for new local build on my setup * ci: updates * fix: variant mapping well enough for android studio build * fix: bundle_or_skip for variants also test it * refactor: cleanup bundle_or_skip * fix: set deps from expo-doctor * fix: expo warning * fix: settings inputs * fix: standarized layout for settings * fix: input selection
1 parent 01481fa commit 76c64c0

29 files changed

Lines changed: 2772 additions & 3471 deletions

.cursor/rules/wsl-unison-setup.mdc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,28 @@ To remove the substitution later:
4848
```cmd
4949
subst X: /d
5050
```
51+
52+
## NativeWind ESM Issue (Metro on Windows)
53+
54+
NativeWind v4 has a known issue where Metro cannot load the config on Windows due to ESM path handling. This causes errors like:
55+
```
56+
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'
57+
```
58+
59+
**Workaround**: Pre-bundle on WSL, then build on Windows.
60+
61+
1. **Pre-bundle on WSL** (when JS/CSS changes):
62+
```bash
63+
cd /home/william/not_connected_to_windows/CalendarNotification
64+
yarn bundle:android --dev=true
65+
```
66+
67+
2. **Build on Windows** (uses pre-built bundle):
68+
```powershell
69+
cd X:\android
70+
.\gradlew assembleDebug
71+
```
72+
73+
The `scripts/bundle_or_skip.js` wrapper automatically detects and copies the pre-built bundle, skipping Metro on Windows. This is configured via `cliFile` in `android/app/build.gradle`.
74+
75+
See: https://github.com/nativewind/nativewind/issues/1667

.github/actions/common-setup/action.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,26 @@ runs:
140140
YARN_INSTALL_STATE_PATH: .yarn/ci-cache/install-state.gz
141141
HUSKY: '0'
142142

143+
# Clean stale native build artifacts from node_modules
144+
# This prevents "duplicate class" errors when dependencies change
145+
# (e.g., react-native-worklets removed since reanimated includes it)
146+
- name: Clean stale node_modules build artifacts
147+
shell: bash
148+
run: |
149+
echo "Cleaning stale native build artifacts from node_modules..."
150+
# Remove android build directories from all node_modules packages
151+
# These get recreated during build but can cause conflicts if cached
152+
find node_modules -path "*/android/build" -type d -prune 2>/dev/null | while read dir; do
153+
echo "Removing: $dir"
154+
rm -rf "$dir"
155+
done
156+
# Also clean any .transforms directories
157+
find node_modules -name ".transforms" -type d -prune 2>/dev/null | while read dir; do
158+
echo "Removing: $dir"
159+
rm -rf "$dir"
160+
done
161+
echo "Cleanup complete"
162+
143163
- name: Restore yarn install state
144164
id: yarn-install-state-cache-restore
145165
uses: actions/cache/restore@v4
@@ -158,7 +178,7 @@ runs:
158178
android/app/src/main/assets/index.android.bundle
159179
android/app/src/main/res/drawable-*
160180
android/app/src/main/res/raw-*
161-
key: ${{ runner.os }}-js-bundle-${{ hashFiles('package.json', 'yarn.lock') }}-${{ hashFiles('src/**/*.{js,jsx,ts,tsx}', 'lib/**/*.{js,jsx,ts,tsx}', 'modules/**/*.{js,jsx,ts,tsx}', 'App.{js,jsx,ts,tsx}', 'index.{js,jsx,ts,tsx}') }}
181+
key: ${{ runner.os }}-js-bundle-${{ hashFiles('package.json', 'yarn.lock') }}-${{ hashFiles('src/**/*.{js,jsx,ts,tsx}', 'lib/**/*.{js,jsx,ts,tsx}', 'app/**/*.{js,jsx,ts,tsx}', 'modules/**/*.{js,jsx,ts,tsx}', 'App.{js,jsx,ts,tsx}', 'index.{js,jsx,ts,tsx}', 'global.css', 'tailwind.config.js') }}
162182
restore-keys: |
163183
${{ runner.os }}-js-bundle-${{ hashFiles('package.json', 'yarn.lock') }}-
164184
${{ runner.os }}-js-bundle-

.github/workflows/actions.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ env:
1919
ANDROID_TARGET: google_apis
2020
ANDROID_ARCH: x86_64
2121
ANDROID_PROFILE: Nexus 5X # Light profile for CI stability (foldable was too resource-heavy)
22-
ANDROID_BUILD_TOOLS_VERSION: "34.0.0"
22+
ANDROID_BUILD_TOOLS_VERSION: "36.0.0"
2323
ANDROID_EMULATOR_MEMORY: 4096 # Increased from 2048 for CI stability
2424

2525
# Define constant for each job to use

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,5 +223,5 @@ fastlane/screenshots
223223
fastlane/test_output
224224
fastlane/readme.md
225225

226-
# react navigation
227-
android/app/src/main/res/drawable-*/node_modules_reactnavigation_elements_lib_commonjs*
226+
# react node_modules stuff
227+
android/app/src/main/res/drawable-*/node_modules_*

android/app/build.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,12 @@ react {
340340
entryFile = layout.projectDirectory.file("../../index.tsx").asFile
341341
// Autolinking - adds dependencies for all autolinked libraries
342342
autolinkLibrariesWithApp()
343+
344+
// Use wrapper script that skips Metro if bundle already exists
345+
// This works around NativeWind Windows ESM issues
346+
// Pre-bundle on WSL: yarn bundle:android --dev=true
347+
// Then Windows builds will use the existing bundle
348+
cliFile = layout.projectDirectory.file("../../scripts/bundle_or_skip.js").asFile
343349
}
344350

345351
// Fix task dependency for RN 0.76+ autolinking (Gradle 8.7 strict validation)

app.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"version": "0.0.1",
66
"platforms": ["android"],
77
"jsEngine": "hermes",
8-
"newArchEnabled": true
8+
"newArchEnabled": true,
9+
"userInterfaceStyle": "automatic"
910
}
1011
}

0 commit comments

Comments
 (0)