Skip to content

Commit

Permalink
NativeModuleSample based on cpp-lib template (#991)
Browse files Browse the repository at this point in the history
## Description

This PR intends to replace the existing sample at
`NativeModuleSample\cppwinrt` with a new `NativeModuleSample\cpp-lib`,
based on the `cpp-lib` template exposed in RNW 0.76.0.

Features of this new sample includes:
* Built-in support for supporting both New and Old Architecture app
projects
* Two example apps (one Old Arch, one New Arch) to showcase the E2E
works
* Upgrade from JS to TS
* Faster native builds thanks to building against the NuGet packages

### Why
The old sample is based on the Old Architecture, UWP-based C++ library
template. That template is not the target of active development, while
the new template is the new standard for RNW >= 0.76.0.

## Screenshots
| Old Arch Example | New Arch Example |
|:-:|:-:|
|
![image](https://github.com/user-attachments/assets/a9d55b72-efeb-4703-9f41-a20c7c699152)
|
![image](https://github.com/user-attachments/assets/125a5b57-09f2-41e3-911c-4c3293928fb2)
|
  • Loading branch information
jonthysell authored Nov 16, 2024
1 parent 286799b commit 86c591d
Show file tree
Hide file tree
Showing 134 changed files with 17,135 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
strategy:
fail-fast: false
matrix:
sampleName: ['NativeModuleSample\cppwinrt', 'NativeModuleSample\csharp']
sampleName: ['NativeModuleSample\cpp-lib', 'NativeModuleSample\cppwinrt', 'NativeModuleSample\csharp']
configuration: ['Debug', 'Release']
platform: ['x86', 'x64', 'ARM64']
uses: ./.github/workflows/template-buildsample.yml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
strategy:
fail-fast: true
matrix:
sampleName: ['NativeModuleSample\cppwinrt', 'NativeModuleSample\csharp']
sampleName: ['NativeModuleSample\cpp-lib', 'NativeModuleSample\cppwinrt', 'NativeModuleSample\csharp']
configuration: ['Debug', 'Release']
platform: ['x86']
uses: ./.github/workflows/template-buildsample.yml
Expand Down
15 changes: 15 additions & 0 deletions samples/NativeModuleSample/cpp-lib/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true

[*]

indent_style = space
indent_size = 2

end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
3 changes: 3 additions & 0 deletions samples/NativeModuleSample/cpp-lib/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.pbxproj -text
# specific for windows script files
*.bat text eol=crlf
82 changes: 82 additions & 0 deletions samples/NativeModuleSample/cpp-lib/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# OSX
#
.DS_Store

# XDE
.expo/

# VSCode
.vscode/
jsconfig.json

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

# Android/IJ
#
.classpath
.cxx
.gradle
.idea
.project
.settings
local.properties
android.iml

# Cocoapods
#
example/ios/Pods

# Ruby
example/vendor/

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

# BUCK
buck-out/
\.buckd/
android/app/libs
android/keystores/debug.keystore

# Yarn
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Expo
.expo/

# Turborepo
.turbo/

# generated by bob
lib/

# React Native Codegen
ios/generated
android/generated
1 change: 1 addition & 0 deletions samples/NativeModuleSample/cpp-lib/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18
1 change: 1 addition & 0 deletions samples/NativeModuleSample/cpp-lib/.watchmanconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

874 changes: 874 additions & 0 deletions samples/NativeModuleSample/cpp-lib/.yarn/releases/yarn-3.6.1.cjs

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions samples/NativeModuleSample/cpp-lib/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
nodeLinker: node-modules
nmHoistingLimits: workspaces

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"

yarnPath: .yarn/releases/yarn-3.6.1.cjs
11 changes: 11 additions & 0 deletions samples/NativeModuleSample/cpp-lib/NuGet.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="react-native" value="https://pkgs.dev.azure.com/ms/react-native/_packaging/react-native-public/nuget/v3/index.json" />
<add key="Nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<disabledPackageSources>
<clear />
</disabledPackageSources>
</configuration>
34 changes: 34 additions & 0 deletions samples/NativeModuleSample/cpp-lib/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Native Module C++ Sample - React Native for Windows

See [../README.md](../README.md) for more details of this sample.

>**Note: Don't build your own projects directly out of this sample. When you publish a native module (as source), you'll want to create a new project with the correct metadata. This will also make sure that you're using unique identifiers in your project files to avoid conflicts with other native modules.**
### Setup

First, make sure you've met the [React Native Windows System Requirements](https://microsoft.github.io/react-native-windows/docs/rnw-dependencies).

Then, install the module's dependencies with yarn and build the TypeScript:

```cmd
yarn install
yarn prepare
```

### Run

To run the example app (targeting the New Architecture) and see that the module works:

```cmd
yarn example windows
```

Alternatively, to run the old example app (targeting the Old Architecture) and see that the module works:

```
yarn example-old windows
```

### Upgrade

**TODO**
5 changes: 5 additions & 0 deletions samples/NativeModuleSample/cpp-lib/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
presets: [
['module:react-native-builder-bob/babel-preset', { modules: 'commonjs' }],
],
};
2 changes: 2 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/.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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
4 changes: 4 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "NativeModuleSampleExampleOld",
"displayName": "NativeModuleSampleExampleOld"
}
12 changes: 12 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const path = require('path');
const { getConfig } = require('react-native-builder-bob/babel-config');
const pkg = require('../package.json');

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

module.exports = getConfig(
{
presets: ['module:@react-native/babel-preset'],
},
{ root, pkg }
);
8 changes: 8 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

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

AppRegistry.registerComponent(appName, () => App);
3 changes: 3 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
preset: 'react-native',
};
67 changes: 67 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const fs = require('fs');
const path = require('path');
const escape = require('escape-string-regexp');
const exclusionList = require('metro-config/src/defaults/exclusionList');
const pack = require('../package.json');

const root = path.resolve(__dirname, '..');
const modules = Object.keys({ ...pack.peerDependencies });

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

//

/**
* Metro configuration
* https://facebook.github.io/metro/docs/configuration
*
* @type {import('metro-config').MetroConfig}
*/
const config = {
watchFolders: [root,
//
],

// We need to make sure that only one version is loaded for peerDependencies
// So we block them at the root, and alias them to the versions in example's node_modules
resolver: {
blacklistRE: exclusionList(
modules.map(
(m) =>
new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`)
).concat([
// This stops "npx @react-native-community/cli run-windows" from causing the metro server to crash if its already running
new RegExp(
`${path.resolve(__dirname, 'windows').replace(/[/\\]/g, '/')}.*`,
),
// This prevents "npx @react-native-community/cli 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/,
])
),

extraNodeModules: modules.reduce((acc, name) => {
acc[name] = path.join(__dirname, 'node_modules', name);
return acc;
},
{
//
}
),
},

transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
38 changes: 38 additions & 0 deletions samples/NativeModuleSample/cpp-lib/example-old/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "native-module-sample-example-old",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start",
"windows": "npx @react-native-community/cli run-windows",
"test:windows": "jest --config jest.config.windows.js"
},
"dependencies": {
"react": "18.3.1",
"react-native": "0.76.0",
"react-native-windows": "0.76.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
"@react-native-community/cli": "15.0.0-alpha.2",
"@react-native-community/cli-platform-android": "15.0.0-alpha.2",
"@react-native-community/cli-platform-ios": "15.0.0-alpha.2",
"@react-native/babel-preset": "0.76.0",
"@react-native/metro-config": "0.76.0",
"@react-native/typescript-config": "0.76.0",
"@rnx-kit/jest-preset": "^0.1.17",
"metro-config": "^0.81.0"
},
"engines": {
"node": ">=18"
},
"react-native-windows": {
"init-windows": {
"name": "NativeModuleSampleExampleOld",
"namespace": "NativeModuleSampleExampleOld",
"template": "old/uwp-cpp-app"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const path = require('path');
const pkg = require('../package.json');

module.exports = {
dependencies: {
[pkg.name]: {
root: path.join(__dirname, '..'),
},
},
};
Loading

0 comments on commit 86c591d

Please sign in to comment.