Skip to content

Commit

Permalink
outline and first drafts for some pages
Browse files Browse the repository at this point in the history
remove broken link

add tutorial outline

restructure

new pages left out of last commit
  • Loading branch information
MaryaBelanger committed Jan 10, 2024
1 parent 78db38c commit b6ddf73
Show file tree
Hide file tree
Showing 9 changed files with 552 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/web/js-interop/dom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: How to interop with DOM APIs
description:
---

{{site.why.learn}}
* How to...
{{site.why.end}}

// *Introdcution paragraphs*

## Background concepts

The following sections provide some extra background and information
around the technologies and concepts used in the tutorial.
To skip directly to the tutorial content,
go to [Steps](#steps).

### Topic/concept 1

### Topic/concept..n

## Steps

### Prerequisites

Before you begin, you'll need...
*

### Actionable step 1

Step subsections should be actionalble, like "Build...", "Retrieve...", "Configure...", etc.

### Actionable step...n

## What next?

Point to other tutorials, reference, etc.
125 changes: 125 additions & 0 deletions src/web/js-interop/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
title: JavaScript interoperability
short-title: JS interop
description: Integrate JavaScript code into your Dart web app.
---

The [Dart web platform](/overview#web-platform) supports communication with
JavaScript apps and libraries, and browser DOM APIs, using the `js_interop`
package, also known as `dart:js_interop`.
Web developers can benefit from using external JS libraries in their Dart code, without
having to rewrite anything in Dart.

## Static interop

The principal model of JS interop in Dart is **static interop**.
Static interop means interop that requires staticly typing external members,
rather than allowing dynamic invocations.
This enables [features](#features) like better performance, type soundness, and more.

Performant static interop model is made possible by **[inline classes][]**.
Inline classes are a special class type that wrap an existing type into a new static type,
without the overhead of a traditional class, enabling zero cost wrapping.

### Why static interop?

Static interop represents the desire to decouple Dart's "core" from the platform
where it's embedded
(*maybe definition of "embedded" or examples here, like the browser, Flutter, etc.?*).

Our [previous iterations of JS interop][] provided the capabillity
to access the embedder, but were not primed to handle that decoupling.
Too much of the process was entwined into the Dart side,
like writing all the bindings to the browser
(*not sure if I understood that note correctly*).
They also had limitations around using the DOM,
typing (which is a cornerstone of Dart),
and expanding to new interop types
(*this is me trying to refer to wasm without actually saying, idk if "interop types" is the right term*).

Static interop addresses all of the shortcomings of Dart's previous JS interop solutions.
Check out the [Features](#features) section for a summary of improvements.

[previous iterations of JS interop]: /web/js-interop/past-js-interop

## Usage

The following example implements inline class-based, static, JS interop in Dart,
using its key members and syntaxes:

```dart
@JS()
library;
// library names aren't cool anymore...
import 'dart:js_interop';
inline class SomeThing {
@JS('JSON.stringify')
external String stringify(Object obj);
}
// idk where `inline` fits into this but basically just show the key components as briefly as possible
```

// *Below the example, go through the steps line by line **and why**:*

1. Append the `@JS` annotation to a `library` directive *so that....*

2. Import `dart:js_interop`, which provides most of the tools needed for static interop,
including annotations, the representation type for inline classes, *... etc.*

3. Create an `inline` class because it *allows you to...*,
which is the core of static interop.

4. Use the `@JS` annotation to call a main-spaced function, or top level external member, from your JS app

// *(or, call the external member from outside an inline class if you don't care about types?*
*idk if that's worth mentioning)*

5. Use the `external` keyword to.... *(allow external and non-external members to communicate? idk)*

6. *show external and non-external members interacting if that's not already shown?*

## Features

Inline class-based static interop enable the following features:

<div class="table-wrapper" markdown="1">
| **Rename external members** | Complex JS member names can be re-written and represented in Dart |
| **Interact external and non-external members** | Process external calls, but "keep it on the type itself" (*idk what that means?*), without writing a separate function |
| **Zero cost wrapping** | Inline classes require virtually no overhead for re-typing external members as static types. (*idk*) |
| **Static error checking** | Since external members must be statically typed, static error checking on types and other parts of the interop is possible (partially sound, more work coming) |
| **Interop with DOM types** | *You can interop with DOM types because...?* |
| **Compatibility with Wasm** | Disallowing generative constructors from the model makes `js_interop` compatible with Wasm |
{:.table .table-striped .nowrap}
</div>


## Up next

For a complete summary of static JS interop concepts, members, and syntaxes:
* The [static interop reference][].

For tutorials and help:
* [How to interop with DOM APIs][]
* [How to interop with JavaScript libraries and apps][]
* [How to test and mock JavaScript interop in Dart][]

For additonal types of documentation on `js_interop`:
* [pub.dev site page][]
* [API reference][]

For information on other iterations of JS interop in Dart:
* [`dart:js_util`][]
* [Past JS interop][]


[inline classes]: /
[static interop reference]: /web/js-interop/reference
[How to interop with DOM APIs]: /web/js-interop/dom
[How to interop with JavaScript libraries and apps]: /web/js-interop/js-app
[How to test and mock JavaScript interop in Dart]: /web/js-interop/test-and-mock
[pub.dev site page]: /
[API reference]: /
[`dart:js_util`]: /web/js-interop/js-util
[Past JS interop]: /web/js-interop/past-js-interop
38 changes: 38 additions & 0 deletions src/web/js-interop/js-app.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
title: How to interop with JavaScript libraries and apps
description:
---

{{site.why.learn}}
* How to...
{{site.why.end}}

// *Introdcution paragraphs*

## Background concepts

The following sections provide some extra background and information
around the technologies and concepts used in the tutorial.
To skip directly to the tutorial content,
go to [Steps](#steps).

### Topic/concept 1

### Topic/concept..n

## Steps

### Prerequisites

Before you begin, you'll need...
*

### Actionable step 1

Step subsections should be actionalble, like "Build...", "Retrieve...", "Configure...", etc.

### Actionable step...n

## What next?

Point to other tutorials, reference, etc.
50 changes: 50 additions & 0 deletions src/web/js-interop/js-util.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: The dart:js_util library
short-title: dart:js_util
description: Overview of the utility library for JS interop
---

[**`dart:js_util` API docs**][]

**We will continue to support `dart:js_util` alongside static interop.**

The `dart:js_util` library, or just `js_util`, is a low-level utility library
for performing JS interop. Because `js_util` is so low-level,
it could potentially be able to provide more flexibility than static interop,
for example, in rare edge cases where `js_interop` is not expressive enough.
This is an exception to the rule;
**please always use static, inline-class based interop by default**.

The `js_util` library is supported by the JS and `dart2wasm` backends.
It is slower and less ergonomic than `js_interop`.

The best example of the difference in ergonomics between `js_interop` and
`js_util` is calling equivalent [`external`][] methods.
Each interop solution generates JavaScript code upon calling an `external` method:

```dart
// js_util external call:
...
// javascript generated:
...
```

The JavaScript code `external` generates for `js_util` is very verbose,
compared to the efficient, compact generation for `js_interop`:

```dart
// js_interop external call:
...
// javascript generated:
...
```

For optimal JS interop, only use `js_util` over static interop if you encounter
a use case that `js_interop` cannot address
(and please [let us know][] if you encounter such a use case).

[**`dart:js_util` API docs**]: {{site.dart-api}}/dart-js_util/dart-js_util-library.html
[`external`]: /web/js-interop/reference#external
[let us know]: https://github.com/dart-lang/sdk/issues/new?assignees=&labels=web-js-interop&template=1_issue_template.md&title=Create+an+issue
6 changes: 6 additions & 0 deletions src/web/js-interop/js_util.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: About `dart:js_util`
description:
---

// *I don't know if this needs to be a page or can just be on the "other" page*
59 changes: 59 additions & 0 deletions src/web/js-interop/past-js-interop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
title: Past JS interop
description: Archive of past JS interop implementations
---

This page addresses previous iterations of JS interop for Dart:
* `package:js`
* `dart:js`

**We do not recommend using any JS interop solution other than [static interop][].**

Each of these tools still exist and are usable.
However, the static interop model
is more performant, provides more capabilities,
and will continue to be supported and developed.
If you are just starting out with JS interop in Dart,
please start with the static interop library, [`js_interop`][].

[static interop]: /web/js-interop
[`js_interop`]: {{site.dart-api}}/js_interop

## `package:js`

// *This section probably doesn't make any sense*

[**`package:js` API docs**]

**We will not continue to support `package:js` alongside static interop.**

The `package:js` library can represent objects in different ways with its
class type annotations:

* [`@JS`]
* [`@anonymous`]
* [`@staticInterop`]

Because `package:js` supports dynamic invocations of external members (the
opposite of static interop), its static type checking capabilities are
much more limited than static interop, and therefore cannot be fully sound.
For the same reason, `package:js` can not interop with [DOM APIs][].

[**`package:js` API docs**]: {{site.pub-pkg}}/js
[`@JS`]: /web/js-interop/reference#js
[`@Anonymous`]: /web/js-interop/reference#others
[`@staticInterop`]: /web/js-interop/reference#staticinterop
[DOM APIs]: /web/js-interop/dom

## `dart:js`

[**`dart:js` API docs**]

**We will not continue to support `dart:js` alongside static interop.**

The `dart:js` library is a low-level API for non-static interop with JavaScript.
It's wrapper-based model requires much more overhead,
and is much more expensive and slow,
than static interop's zero-cost wrapper model.

[**`dart:js` API docs**]: {{site.dart-api}}/dart-js/dart-js-library.html
Loading

0 comments on commit b6ddf73

Please sign in to comment.