microsoft / Windows-Dev-Performance

A repo for developers on Windows to file issues that impede their productivity, efficiency, and efficacy
MIT License
438 stars 21 forks source link

Add support for a JavaScript projection of the Windows Runtime API #25

Closed asklar closed 8 months ago

asklar commented 4 years ago

Migrated from https://github.com/microsoft/react-native-windows/issues/4759 as that request isn't react native windows specific. Original filed by @dstaley

Proposal: Add support for a JavaScript projection of the Windows Runtime API

Summary

As a JavaScript developer, I'd like to be able to call Windows Runtime APIs without writing a native module in an unfamiliar language such as C++ or C#.

Motivation

As a JavaScript developer building a Windows app with React Native, I'd like to avoid having to switch languages to call useful Windows Runtime APIs. Since there's already a precedent for the Windows Runtime supporting multiple language projections (C++, C#, and now Rust), and, most importantly, since there was already a JavaScript language projection at one point, it would be great for React Native for Windows to support calling these APIs from JavaScript either out of the box or through an easily-installable module.

Basic example

External Package

import CryptographicBuffer from 'react-native-windows-runtime/security/cryptography';

const num = CryptographicBuffer.GenerateRandomNumber();

Built-in

import { NativeModules } from 'react-native';
const { CryptographicBuffer } = NativeModules.Windows.Security.Cryptography;

const num = CryptographicBuffer.GenerateRandomNumber();

Open Questions

The biggest question I have is whether this is possible given that React Native for Windows uses JSC/Hermes, whereas I believe the JavaScript projection was only ever supported in ChakraCore.

bitcrazed commented 4 years ago

Great ask. Email sent. Will update soon.

shirakaba commented 4 years ago

Hoping this contributes to the discussion, but NativeScript might be a perfect fit here.

NativeScript UWP runtime

NativeScript's unfinished UWP runtime aimed to allow Windows Runtime APIs to be called synchronously from JavaScript, with two-way marshalling of all data types between the native and JS contexts (not just JSON-serialisable ones) and auto-generation of TypeScript typings.

The biggest question I have is whether this is possible given that React Native for Windows uses JSC/Hermes, whereas I believe the JavaScript projection was only ever supported in ChakraCore.

The NativeScript UWP runtime was built on JSC, so it has potential.

NativeScript runtimes for other platforms and JS engines

Furthermore, NativeScript also provide matching iOS JSC, iOS V8, and Android V8 runtimes, which are complete. So it's a pattern that could potentially be extended to all platforms.

Examples of NativeScript API access

Here's a simple example of what native API access looks like in NativeScript for iOS and Android, in React NativeScript (my React wrapper around NativeScript):

https://github.com/shirakaba/nativescript-grimoire/tree/master/battery%20level

And a more complex example just for iOS, giving the equivalent Swift APIs:

https://github.com/shirakaba/nativescript-grimoire/tree/master/text%20tokenisation

Playground

I've made TypeScript playgrounds for NativeScript iOS and NativeScript Android to show what the dev experience is like. Unfortunately I never made one for Windows as no TypeScript typings were published. Perhaps TypeScript typings may be generated if the NativeScript UWP runtime is built as per the repo's instructions.

Caveats

NativeScript is not embeddable, and is likely to remain that way for the foreseeable future. For now, the NativeScript JS engine works by making a fork of JSC or V8 (this is necessary, for example, to coordinate references and garbage collection of native types marshalled into the JS context). I don't know what would be involved in making it embeddable into arbitrary environments like React Native or Electron.

The NativeScript UWP runtime is also unfinished (having been abandoned with the death of Windows Phone), so it would have to be pushed to completion before being a viable option.

JonFerraiolo commented 3 years ago

Personally, I think it would be a mistake to implement this feature optimized for and constrained by one library/toolkit or a subset of libraries. I am old enough to remember when almost everyone used jQuery. So, my wish is that WinRT is available to any JavaScript with the requirements and constraints only due to Microsoft technologies. Then, leave it to the react native team to make whatever bridges they need to make.

AdamBraden commented 8 months ago

This was announced a while ago:

https://devblogs.microsoft.com/react-native/announcing-rnwinrt/ https://github.com/microsoft/react-native-winrt