Coder Social home page Coder Social logo

continuity's Introduction

Microsoft React-Native SDK

A platform that makes it easy to blend react-native components into your native application.

Building

The build is based on CMake and Ninja.

Windows

If you already have Visual Studio 2017 installed with C++ tools, skip to step 3.

  1. Install Visual Studio 2017 build tools
choco install visualstudio2017buildtools
choco install visualstudio2017-workload-vctools
choco install visualstudio2017-workload-universalbuildtools
  1. Install a Windows 10 SDK. Choose a recent release. Don't go back any farther than 10.0.15063.0 (Spring Creators Update, version 1703).

  2. Download NuGet. Choose the command-line version. Add it to your PATH.

  3. Run the build

scripts\build-windows.cmd
scripts\test-windows.cmd

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

continuity's People

Contributors

afoxman avatar microsoft-github-operations[bot] avatar microsoftopensource avatar rnbot avatar rnsdkbot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

continuity's Issues

Runtime configuration should not be part of the manifest

Any properties that control runtime behavior should not be in the manifest. Instead, they should come from the native host app because the host knows what the user is doing and can also query the operating system for contextual info. For example, the host should know that it is part of a test app or a real app, and whether that app is running on a developer's machine or a customer's machine. It can also conditionally query the OS for other processes, such as a running packager.

The host should only read runtime configuration from cross-platform systems such as environment variables or files. Hosts should avoid platform-specific systems like the registry and plist files, since each adds complexity to the developer's experience.

The following runtime properties should be removed from the manifest:

  "runtime": {
    "devMode"
    "attachToWebDebugger"
    "liveReload"
    "byteCodeCaching"
  },
  "packager": {
    "environment"
    "host"
    "fileName"
    "extension"
    "minify"
  },
  "webDebugHost"

Import the Win32 C++ executor into the Office build

Create automation to publish the headers and the code using a NuGet package stamped with the version number from the version file. Prefer to use an ADO CI loop for this. Alternatively, start with a script that is run manually after every merged PR.

In the Office source tree, pull in the executor NuGet package. Incorporate it into the build, and verify that production apps and test apps continue to work as expected.

Document the manifest schema

Write markdown documentation for the manifest schema.

Write a library of typescript types which model the schema. Make sure they are usable in VS Code projects.

These artifacts should live in the manifest project within this repo.

Port the C++ executor to iOS and macOS

Port the Win32 C++ executor to iOS and macOS. The core code should remain largely unchanged. The bulk of this work should be creating a build environment and providing platform-specific implementations such as memory-mapped files.

Export podspecs and any other artifacts necessary to enable autolinking.

This task will require that the manifest reader be ported as well, though that code should be usable as-is, short of any new build logic.

Do not spend time importing these platforms into the Office source tree. Instead, build them directly from GitHub using an OSS test project. All dependencies, including react-native, should be available publicly. The test project should validate autolinking.

Some manifest data should be localized

Any manifest data that is shown on-screen must be localizable. For example, component > displayName.

There is no localization framework in place for the development environment, so that is the first step.

UI configuration should be part of each component, and there should be multiple entries for the host to choose from

"win32" > "container" only allows one 'view' to be defined for all apps in a bundle, which isn't right.

Each component should define its own views, and there should be an array of choices. The host should choose the appropriate view, by name, at runtime, based on context from the native host app.

type ViewType = 'dialog' | 'taskpane';

interface ComponentView {
  "type": ViewType;
}

interface DialogView : ComponentView {
  "type": 'dialog';
  "width": number; // optional; unusure of default behavior
  "height": number; // optional; unusure of default behavior
  "showOkButton": boolean; // defaults to false
  "showCancelButton": boolean; // defaults to false
}

interface TaskPaneView: ComponentView {
  "type": 'taskpane';
  "msotbid": number; // MSOTBID number; defaults to 1
}

// component definition
{
  ... ,
  "views": {
    [viewName: string]: DialogView | TaskPaneView;
  }
}

Use @microsoft/react-native-test-app as the defacto E2E test framework

We should adopt @microsoft/react-native-test-app as the de facto test framework for E2E testing. It lets hosts pull in our code, the test framework, and a collection of react-native apps, and stitch them all up into a single test app. And everything is driven from data in the app manifests (test creation/execution).

To make this work, the app needs to express how it should be tested. For examples, what surfaces should the app be run in, and what are the initial props and dev settings to use when running the tests.

These test cases likely belong in the manifest. They should be stripped out when making a production/aggregated manifest, though, as they aren't used on client machines.

The first step is a discussion between @acoates-ms and @tido64 to agree on a manifest schema.

Remove Office-specific properties from manifest

This issue depends on #6 (Manifest extensibility model).

"msotbid" should be removed from the 'taskpane' view configuration. Office should instead access this as an app-specific manifest property.

Apple builds

Add build support and CI loops for iOS and macOS.

Create a C++ executor library targeting the Win32 platform

General guidance

  • All APIs are shared (multi-threaded)
  • All objects should be reference-counted for safe destruction
  • Events can be used to call APIs, making re-entrant deadlocks and infinite looping a possibility

Core Library

Make an executor for holding state as the library is built out. The host will use the executor as its primary interface, and listen for app lifecycle events.

Put the code in an executor library project, not in the root.

Institute a version file for this library. It should be bumped as part of the PR, and the PR validation should fail if the bump isn't included.

Memory-mapped files

Make an interface which represents a memory-mapped file. Open, Close, and GetData -> std::string_view. Build a Windows implementation only at this time.

This will be used primarily for reading JavaScript bundle and library files.

App registry

The host registers each app group's root directory with the executor.

The executor reads the manifest from the root directory. It builds a list of app name/version pairs, adding each one to the registry map. App name/version is the map key, and the entry is a shared app group object. The app group contains the root directory and manifest.

If any name/version pair already exists in the map, registration of the entire group fails -- without modifying anything.

Launching an app

The host launches an app using its name and version. Launching happens in two steps. First, the host gets an app instance, which is a container for all JavaScript resources. Second, the host creates a rendering surface for the app and invokes the app's JavaScript entry-point. The host can skip the second step if it only wants to "warm up" an app.

Creating an app instance

Getting an app instance is complex. The host uses name/version to find the app group in the registry. The host then queries the app group to see if it has an active app instance. If not, the host directs the group to create a new instance, passing in "runtime" props as input: dev settings and packager config.

When creating an instance, the executor first verifies that the app's JavaScript code is compatible with the host's native code. Specifically, it checks that the react-native versions are compatible (same major/minor, JS patch >= native patch), and that all required native modules are available (no version checks). The executor then initializes all native modules, optionally passing in a pointer (unowned) to the parent app instance. Finally, the executor memory-maps the JavaScript bundle & library files and creates the react-native instance around them, causing JS code to be read and parsed.

NOTE: Instance creation is slow and resource-intensive. The host is responsible for gating its use of the executor to avoid a create-race.

Starting the app

The host tells the executor to start the app using a set of initial properties.

The executor queries the instance to find out if the app is running. Attempting to start an already-running app results in an error.

The executor creates a rendering surface for the app using data in the manifest. For example, the surface could be a 'dialog' view with a specific size and optional buttons for OK and Cancel. The surface is attached to the react-native instance, making it available for render() calls.

The executor then invokes the app's JavaScript entry-point, passing in the set of initial properties from the host. This causes the app to run. All communication with the host from this point onward will be through native modules and executor events.

Move C++ manifest reader library from Office development tree

Move the C++ manifest reader library from Office's internal source tree to this public repo. Put the code in a manifest library project, not in the root. Don't include Office build files, just the headers and the code. Do not include the host-integration library, as that is Office-specific and irrelevant to OSS consumers.

Ensure the public API / ABI is stable. Simple types or IUnknown. Explicit calling convention.

Institute a version file for this library. It should be bumped as part of the PR, and the PR validation should fail if the bump isn't included.

Create automation to build a DLL and publish with headers into a NuGet package using the version number from the version file. Prefer to use an ADO CI loop for this. Alternatively, start with a script that is run manually after every merged PR.

Back in the Office source tree, delete the reactnative_platformsdk project and instead pull in DLL/headers via NuGet. Incorporate it into the build, and verify that internal test apps and in-app hooks continue to work as expected.

Development Environment: use manifest to set asset location in the CLI configuration file

The react-native CLI is the standard mechanism for generating the code & scaffolding needed for a react-native app. CLI uses an optional configuration file which is solely focused on building the app. It identifies app code (JS and native), dependencies, assets, and target platforms.

Our manifest overlaps with the CLI configuration in one area: locating app assets. Our development environment uses the CLI internally already. We’ll expand on that to include setting the CLI’s asset location from our manifest.

Rationalize our manifest with Expo's manifest

Expo’s manifest serves the same purpose as our manifest. There are a few Expo properties we overlap with: name, description, slug, owner, version, platforms, and githubUrl. The rest of Expo’s manifest is used to configure Expo’s native modules.

We should be aligned with Expo on the meaning and purpose of these fields. There may be an opportunity to share code or schema files, as well.

Manifest extensibility model

Apps can extend the manifest by adding their own data. To minimize future conflicts between new manifest props and app props, we need to come up with guidelines for naming & placement. As a general rule, app props should be able to go almost anywhere in the manifest, so they can stay close to related manifest props.

We won't do anything at runtime to enforce this. No schema validation, no checks to see that app props conform.

Apps will access their props through a read-only copy of the manifest.

We'll make it available to JavaScript via a native module that is included with the manifest reader library. The entire manifest will come through as a "constant" which means access to it will be synchronous & read-only. Native code in the app or the host can also access the manifest by doing what the native module does (or interacting with the native module instead to get at its data).

This all works because the manifest is immutable at runtime.

ARM support

Add the ARM architecture to Win32 and Android builds.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.