Skip to content
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

Create example for Windows #2312

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 2 additions & 0 deletions WindowsExample/.bundle/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BUNDLE_PATH: "vendor/bundle"
BUNDLE_FORCE_RUBY_PLATFORM: 1
4 changes: 4 additions & 0 deletions WindowsExample/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
root: true,
extends: '@react-native',
};
74 changes: 74 additions & 0 deletions WindowsExample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# OSX
#
.DS_Store

# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
**/.xcode.env.local

# Android/IntelliJ
#
build/
.idea
.gradle
local.properties
*.iml
*.hprof
.cxx/
*.keystore
!debug.keystore

# node.js
#
node_modules/
npm-debug.log
yarn-error.log

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/

**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/screenshots
**/fastlane/test_output

# Bundle artifact
*.jsbundle

# Ruby / CocoaPods
**/Pods/
/vendor/bundle/

# Temporary files created by Metro to check the health of the file watcher
.metro-health-check*

# testing
/coverage

# Yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
1 change: 1 addition & 0 deletions WindowsExample/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
3 changes: 3 additions & 0 deletions WindowsExample/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import App from '../apps';

export default App;
8 changes: 8 additions & 0 deletions WindowsExample/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
source 'https://rubygems.org'

# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
ruby ">= 2.6.10"

# Exclude problematic versions of cocoapods and activesupport that causes build failures.
gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
1 change: 1 addition & 0 deletions WindowsExample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# React Native Screens example app for windows
17 changes: 17 additions & 0 deletions WindowsExample/__tests__/App.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* @format
*/

import 'react-native';
import React from 'react';
import App from '../App';

// Note: import explicitly to use the types shipped with jest.
import {it} from '@jest/globals';

// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('renders correctly', () => {
renderer.create(<App />);
});
4 changes: 4 additions & 0 deletions WindowsExample/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "WindowsExample",
"displayName": "WindowsExample"
}
3 changes: 3 additions & 0 deletions WindowsExample/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
};
9 changes: 9 additions & 0 deletions WindowsExample/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* @format
*/

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);
3 changes: 3 additions & 0 deletions WindowsExample/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
preset: 'react-native',
};
115 changes: 115 additions & 0 deletions WindowsExample/metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const path = require('path');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const escape = require('escape-string-regexp');
const pack = require('../package.json');

const projectPack = require('./package.json');
const resolvedExts = ['.ts', '.tsx', '.js', '.jsx'];

const root = path.resolve(__dirname, '..');
const projectNodeModules = path.join(__dirname, 'node_modules');

const fs = require('fs');
const rnwPath = fs.realpathSync(
path.resolve(require.resolve('react-native-windows/package.json'), '..'),
);

const modules = [...Object.keys(pack.peerDependencies), 'react-native-windows'];

const config = {
projectRoot: __dirname,
watchFolders: [root],

// We need to make sure that only one version is loaded for peerDependencies
// So we exclude them at the root, and alias them to the versions in example's node_modules
resolver: {
blockList: exclusionList(
modules.map(
m => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`),
),
// This stops "react-native run-windows" from causing the metro server to
// crash if its already running
new RegExp(
`${path.join(__dirname, 'windows').replace(/[/\\]+/g, '/')}.*`,
),
new RegExp(`${path.join(__dirname, 'macos').replace(/[/\\]+/g, '/')}.*`),
// This prevents "react-native run-windows" from hitting: EBUSY: resource busy or locked, open msbuild.ProjectImports.zip or other files produced by msbuild
new RegExp(`${rnwPath}/build/.*`),
new RegExp(`${rnwPath}/target/.*`),
/.*\.ProjectImports\.zip/,
),
nodeModulesPaths: [projectNodeModules, path.join(__dirname, '../../')],
extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
}, {}),

// Since we use react-navigation as submodule it comes with it's own node_modules. While loading
// react-navigation code, due to how module resolution algorithms works it seems that its node_modules
// are consulted first, resulting in double-loaded packages (so doubled react, react-native and other package instances) leading
// to various errors. To mitigate this we define below custom request resolver, hijacking requests to conflicting modules and manually
// resolving appropriate files. **Most likely** this can be achieved by proper usage of blockList but I found this method working ¯\_(ツ)_/¯
resolveRequest: (context, moduleName, platform) => {
if (moduleName === 'react-native-screens') {
return {
filePath: path.join(root, 'src', 'index.tsx'),
type: 'sourceFile',
};
}

if (moduleName in projectPack.dependencies) {
for (const ext of resolvedExts) {
const possiblePath = path.join(
__dirname,
'node_modules',
moduleName,
`index${ext}`,
);

const possibleSrcPath = path.join(
__dirname,
'node_modules',
moduleName,
'src',
`index${ext}`,
);

if (fs.existsSync(possiblePath)) {
return {
filePath: possiblePath,
type: 'sourceFile',
};
} else if (fs.existsSync(possibleSrcPath)) {
return {
filePath: possibleSrcPath,
type: 'sourceFile',
};
}
}
}

// Optionally, chain to the standard Metro resolver.
return context.resolveRequest(context, moduleName, platform);
},
},

transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
},
}),
// This fixes the 'missing-asset-registry-path` error (see https://github.com/microsoft/react-native-windows/issues/11437)
assetRegistryPath: 'react-native/Libraries/Image/AssetRegistry',
},
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
Binary file added WindowsExample/msbuild.binlog
Binary file not shown.
55 changes: 55 additions & 0 deletions WindowsExample/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "WindowsExample",
"version": "0.0.1",
"private": true,
"scripts": {
"lint": "eslint .",
"start": "react-native start",
"test": "jest",
"postinstall": "patch-package",
"windows": "react-native run-windows"
},
"dependencies": {
"@react-navigation/bottom-tabs": "link:../react-navigation/packages/bottom-tabs/",
"@react-navigation/core": "link:../react-navigation/packages/core/",
"@react-navigation/drawer": "link:../react-navigation/packages/drawer/",
"@react-navigation/elements": "link:../react-navigation/packages/elements/",
"@react-navigation/native": "link:../react-navigation/packages/native/",
"@react-navigation/native-stack": "link:../react-navigation/packages/native-stack/",
"@react-navigation/routers": "link:../react-navigation/packages/routers/",
"@react-navigation/stack": "link:../react-navigation/packages/stack/",
"patch-package": "^8.0.0",
"postinstall-postinstall": "^2.1.0",
"react": "18.3.1",
"react-dom": "^18.2.0",
"react-native": "0.74.2",
"react-native-gesture-handler": "^2.17.1",
"react-native-reanimated": "3.14.0",
"react-native-restart": "^0.0.27",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "link:../",
"react-native-vector-icons": "^8.0.0",
"react-native-windows": "0.74.9"
},
"devDependencies": {
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/babel-preset": "0.75.1",
"@react-native/eslint-config": "0.75.1",
"@react-native/metro-config": "0.75.1",
"@react-native/typescript-config": "0.75.1",
"@types/react": "^18.2.6",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.6.3",
"eslint": "^8.19.0",
"jest": "^29.6.3",
"metro-config": "^0.80.10",
"prettier": "2.8.8",
"react-test-renderer": "18.3.1",
"typescript": "5.0.4"
},
"engines": {
"node": ">=18"
}
}
Loading
Loading