Skip to content

Commit 1b9159f

Browse files
authored
docs: improve multiple marko versions (#125)
1 parent 5ea79a3 commit 1b9159f

File tree

4 files changed

+100
-10
lines changed

4 files changed

+100
-10
lines changed

docs/guide/marko-5-interop.md

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,91 @@
1-
# Using Marko 5 and Marko 6 together
1+
# Using Multiple Marko Versions
22

3-
All Marko 5 apps are equipped to use tags API components without any changes. To use both Marko 5 and Marko 6 together, ensure that Marko 5 is installed at the project root.
3+
> [!TLDR]
4+
> - `marko@6` is _not_ backward compatible
5+
> - `marko@5` is **forward compatible**
6+
> - In Marko 5, heuristics determine runtime version per-tag
7+
8+
[Marko 5](https://v5.markojs.com/) uses the [Class API](https://v5.markojs.com/docs/class-components/), and current versions use the [Tags API](../reference/language.md). Marko 6 is _not_ backwards compatible, so if `marko@6` is installed an application cannot use class components out of the box. Instead, Marko 5 is **forward compatible**. To use multiple versions of Marko together, ensure that Marko 5 is installed at the project root.
9+
10+
Marko 5 and 6 use runtimes which are **interoperable** but **distinct**. As such, the compiler determines which runtime to use based on a set of heuristics. Switching _between_ the two runtimes should be avoided as often as possible, so it is preferable to ensure that Tags API components mostly reference other Tags API components.
11+
12+
## Tags/Class API Heuristics
13+
14+
The Marko 5 compiler uses a set of heuristics to determine which runtime a template should be compiled to.
15+
16+
> [!NOTE]
17+
> These rules are listed in order of precedence, so once _one_ is satisfied none of the others are checked.
18+
19+
### Directory Name
20+
21+
In Marko 5 and below custom tags were [auto-discovered](../reference/custom-tag.md#relative-custom-tags) from `/components` directories, but in Marko 6 they are discovered from `/tags`. Since `/tags` is new to Marko 6, `.marko` files under `/tags` **must** use the Tags API.
22+
23+
### Comment Opt-In
24+
25+
Files can be explicitly marked to use a specific API with a `/* use [api] */`comment. Any comment type is acceptable, and the comment can be anywhere in the file.
26+
27+
```marko
28+
// use class
29+
<h1>Class API</h1>
30+
```
31+
32+
```marko
33+
<!-- use tags -->
34+
<h1>Tags API</h1>
35+
```
36+
37+
> [!TIP]
38+
> These explicit opt-ins are only necessary if a `.marko` file _isn't_ an [auto-discovered tag](#directory-name) and its contents are ambiguous (i. e. none of the following heuristics apply) so in practice they are rarely needed except for sometimes in [Marko Run](../marko-run/file-based-routing.md)'s `+page.marko` and `+layout.marko`.
39+
40+
### Class API Syntax
41+
42+
If an otherwise ambiguous file contains any of the following syntax, it is detected as Class API (Marko 5):
43+
44+
- A [`class {}` block](https://v5.markojs.com/docs/class-components/#single-file-components)
45+
- A [`style {}` block](https://v5.markojs.com/docs/class-components/#styles)
46+
- Inline JS in a [`$ scriptlet;`](https://v5.markojs.com/docs/syntax/#inline-javascript)
47+
- An [Attribute argument](https://v5.markojs.com/docs/syntax/#arguments) (`<button onClick("handleClick")>`)
48+
- An attribute modifier ([`:scoped`](https://v5.markojs.com/docs/class-components/#scoped) or [`:no-update`](https://v5.markojs.com/docs/class-components/#no-update_1))
49+
- Any of [these tags](https://github.com/marko-js/marko/blob/main/packages/runtime-tags/src/translator/interop/feature-detection.ts#L182-L190):
50+
- `<await-reorderer>` `<class>` `<include-html>` `<include-text>` `<init-components>` `<macro>` `<module-code>` `<while>`
51+
52+
### Tags API Syntax
53+
54+
If an otherwise ambiguous file contains any of the following syntax, it is detected as Tags API (Marko 6):
55+
56+
- A [tag variable](../reference/language.md#tag-variables) (`<div/var>`)
57+
- The [bind shorthand](../reference/language.md#shorthand-change-handlers-two-way-binding) (`:=`)
58+
- Any of [these tags](https://github.com/marko-js/marko/blob/main/packages/runtime-tags/src/translator/interop/feature-detection.ts#L191-L200):
59+
- `<const>` `<debug>` `<define>` `<id>` `<let>` `<lifecycle>` `<log>` `<return>` `<try>`
60+
61+
```marko
62+
<let/count=0>
63+
<button onClick() { count++ }>${count}</button>
64+
```
65+
66+
### Exclusive Tag Library
67+
68+
If a file is otherwise ambiguous but _all_ tags found by the [tag discovery mechanism](../reference/custom-tag.md#relative-custom-tags) are in a `tags/` directory and no `components/` directories are discovered, the file falls back into Tags API.
69+
70+
All ambiguous files here use the tags API, because there are no `components/`.
71+
72+
```
73+
src/
74+
+page.marko // Tags API
75+
tags/
76+
some-tag.marko
77+
```
78+
79+
Even _one_ `components/` directory will default all ambiguous files to prefer Class API if there are no [`// use tags` comments](#-use-api) or [tag syntax heuristics](#tags-api-syntax).
80+
81+
```
82+
src/
83+
components/
84+
some-component.marko
85+
some-page/
86+
+page.marko // Class API
87+
tags/
88+
another-tag.marko
89+
tags/
90+
some-tag.marko
91+
```

docs/reference/custom-tag.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ Custom Tags in Marko allow for reusing markup across the application.
66

77
When you use a `<Tag>` in Marko it is resolved in the following order:
88

9-
- [Custom Tag Discovery](#custom-tag-discovery)
10-
- [Priority](#priority)
11-
- [Local Variable Custom Tags](#local-variable-custom-tags)
12-
- [Relative Custom Tags](#relative-custom-tags)
13-
- [Installed Custom Tags](#installed-custom-tags)
14-
- [Supporting Files](#supporting-files)
9+
- [Local Variable Custom Tags](#local-variable-custom-tags) <!-- this isn't a table of contents, prettier 😠 -->
10+
- [Relative Custom Tags](#relative-custom-tags)
11+
- [Installed Custom Tags](#installed-custom-tags)
12+
- [Supporting Files](#supporting-files)
1513

1614
## Local Variable Custom Tags
1715

@@ -82,7 +80,10 @@ And the file `pages/about/page.marko` can resolve:
8280
- `<app-footer>`
8381
- `<team-members>`
8482
85-
The `home` page can't resolve `<team-members>` and the `about` page can't resolve `<home-banner>`. By using nested `tag/` directories, we've scoped our page-specific tags to their respective pages.
83+
The `home` page can't resolve `<team-members>` and the `about` page can't resolve `<home-banner>`. By using nested `tags/` directories, we've scoped our page-specific tags to their respective pages.
84+
85+
> [!NOTE]
86+
> In previous versions, relative tags were discovered in `components/` directories instead of `tags/`. These directories are now used as a heuristic for [runtime interoperability](../guide/marko-5-interop.md).
8687
8788
## Installed Custom Tags
8889

public/llms.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Marko's key features include:
4747
- [Publishing Components](/docs/guide/publishing-components.md): Publishing reusable components
4848
- [Low-level APIs](/docs/guide/low-level-apis.md): Advanced low-level APIs
4949
- [Duplicate Form Submissions](/docs/guide/duplicate-form-submissions.md): Preventing duplicate submissions
50-
- [Marko 5 Interop](/docs/guide/marko-5-interop.md): Interoperability with Marko 5
50+
- [Using Multiple Marko Versions](/docs/guide/marko-5-interop.md): Interoperability with Marko 5
5151

5252
## Explanation
5353

src/tags/app-menu/app-menu.marko

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ div#site-menu class=styles.menu
3434
strong -- Guides
3535
ul
3636
Page="/docs/guide/styling" -- Styling
37+
Page="/docs/guide/marko-5-interop" -- Marko 5 Interop
3738
li
3839
strong -- Explanation
3940
ul

0 commit comments

Comments
 (0)