Skip to content

Commit c28138e

Browse files
committed
feat: rework Author a Fable library page
1 parent 50ed3b0 commit c28138e

File tree

1 file changed

+64
-113
lines changed

1 file changed

+64
-113
lines changed
Lines changed: 64 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,87 @@
11
---
2-
title: Author a Fable library
2+
title: Author a Fable package
33
layout: standard
4+
toc:
5+
to: 3
46
---
57

6-
## Requirements
8+
## Use Glutinum.Template
79

8-
To write a library that can be used in Fable you need to fulfill a few conditions:
10+
[Glutinum.Template](https://github.com/glutinum-org/Glutinum.Template) is a template that can help you create a Fable package.
911

10-
- Don't use FSharp.Core/BCL APIs that are not [compatible with Fable](../dotnet/compatibility.html).
11-
- Keep a simple `.fsproj` file: don't use MSBuild conditions or similar.
12-
- Include the source files in the Nuget package in a folder named `fable`.
12+
To use this template, you can run the following command:
1313

14-
:::info
15-
If your library is a pure binding, you can skip this step.
14+
```bash
15+
dotnet new -i "Glutinum.Template::*"
16+
```
1617

17-
This will improve Fable compilation time as the compiler will not need to parse the source files of the binding.
18-
:::
18+
Then you can create a new project with:
1919

20-
Add the following to your `.fsproj` file:
20+
```bash
21+
dotnet new glutinum -n MyProject
22+
```
2123

22-
```xml
23-
<!-- Add source files to "fable" folder in Nuget package -->
24-
<ItemGroup>
25-
<!-- Include all files that are compiled with this project -->
26-
<Content Include="@(Compile)" Pack="true" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
27-
<!-- Include the project file itself as well -->
28-
<Content Include="$(MSBuildThisFileFullPath)" Pack="true" PackagePath="fable/" />
29-
</ItemGroup>
30-
```
24+
Once installed, you can refer to the [`MANUAL.md`](https://github.com/glutinum-org/Glutinum.Template/blob/main/content/MANUAL.md) file in the generated project for more information.
3125

32-
If you needs native files like `.js` or `.py`, you need to include them in the `fable` folder as well.
26+
## Use Fable.Package.SDK directly
3327

34-
Example:
28+
If you prefer to not use a template, here are the steps to author a Fable package manually.
3529

36-
```xml
37-
<ItemGroup>
38-
<!-- Your F# code is already included because of the previous rules, so you only need to ensure the .js files are included as well -->
39-
<Content Include="**/*.js" Exclude="**\*.fs.js" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
40-
</ItemGroup>
41-
```
30+
Install Fable.Package.SDK
4231

43-
:::info
44-
Note that you don't want to include Fable generated files and so we exclude them with `Exclude="**\*.fs.js"`
45-
:::
32+
[Fable.Package.SDK](https://github.com/fable-compiler/Fable.Package.SDK) is a set of MSBuild targets that can help you create a Fable package.
4633

47-
In order to publish the package to Nuget check [the Microsoft documentation](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli) or alternatively you can also [use Fake](https://fake.build/dotnet-nuget.html#Creating-NuGet-packages).
34+
**.NET CLI**
4835

49-
## Make your package usable by others
36+
```bash
37+
dotnet add package Fable.Package.SDK
38+
```
5039

51-
In addition to the source files, there are a few things you should do to make your package easier to consume by others. Adding these items will improve the development experience for your users inside their editors,
52-
specifically enabling Go To Definition (F12 in most editors) to work on your library's code.
40+
This will add the package to your project file.
5341

5442
```xml
55-
<PropertyGroup>
56-
<!-- Ensure debugging information is easily found, so that editors can locate the source code locations for your library.
57-
This slightly increases the size of your package, but the usability benefits are worth it. -->
58-
<DebugType>embedded</DebugType>
59-
<!-- Ensure that files that are generated during the build by the .NET SDK are also included in your compiled library. -->
60-
<EmbedUntrackedSources>true</EmbedUntrackedSources>
61-
</PropertyGroup>
43+
<PackageReference Include="Fable.Package.SDK" Version="x.y.z" />
44+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
45+
<PrivateAssets>all</PrivateAssets>
46+
</PackageReference>
6247
```
6348

64-
## Make your package discoverable
65-
66-
[Fable.Packages](https://fable.io/packages/) is a tool making it easy for users to search for Fable packages.
67-
68-
To make your packages listed on Fable.Packages, you need to add some tags to your `.fsproj`.
69-
70-
<ul class="textual-steps">
71-
72-
<li>
73-
74-
**All Fable** packages must have the `fable` tag.
75-
76-
</li>
77-
78-
<li>
79-
80-
Specify what kind of package you are publishing.
81-
82-
A fable package can be one of the following:
83-
84-
- `fable-library`: A library that can be used in Fable
85-
86-
Examples of libraries could be [Fable.Promise](https://github.com/fable-compiler/fable-promise/), [Elmish](https://elmish.github.io/), [Thoth.Json](https://thoth-org.github.io//Thoth.Json/), [Feliz](https://zaid-ajaj.github.io/Feliz/)
87-
88-
<div></div> <!-- Force a space to improve visual -->
89-
90-
- `fable-binding`: The package consist of a set of API to make a native library available
91-
92-
For example:
93-
94-
- A package which makes an NPM package API available
95-
- A package which makes the Browser API available
96-
- A package which makes a cargo package API available
49+
These rules are necessary to ensure that the package is not included in the final package, you don't want you package to depend on `Fable.Package.SDK` at runtime.
9750

98-
</li>
51+
**Paket**
9952

100-
<li>
53+
```bash
54+
# In your paket.dependencies
55+
nuget Fable.Package.SDK copy_local: true
10156

102-
Specify which targets are supported by your package.
57+
# In your paket.references
58+
Fable.Package.SDK
59+
```
10360

104-
Choose one or more of the following tags:
61+
You can then refer to the [Fable.Package.SDK documentation](https://github.com/fable-compiler/Fable.Package.SDK) for more information.
10562

106-
- `fable-dart`: Dart is supported by the package
107-
- `fable-dotnet`: .NET is supported by the package
108-
- `fable-javascript`: JavaScript is supported by the package
109-
- `fable-python`: Python is supported by the package
110-
- `fable-rust`: Rust is supported by the package
111-
- `fable-all`: Package is compatible with all Fable targets.
63+
## Guidelines
11264

113-
:::warning
114-
A package can be compatible with all targets if it depends only on packages that are also compatible with all targets.
65+
### Include native files
11566

116-
A package compatible with all targets cannot be a binding, as these are target-specific.
117-
:::
67+
If you needs native files like `.js` or `.py`, you need to include them in the `fable` folder as well.
11868

11969
Example:
12070

121-
If your package supports only JavaScript you need to use `fable-javascript`
122-
123-
If your package supports both JavaScript and Python, you need to use `fable-javascript` and `fable-python`
124-
125-
</li>
126-
127-
</ul>
128-
129-
Examples:
130-
131-
If your package is a binding which target JavaScript you need to write:
132-
13371
```xml
134-
<PropertyGroup>
135-
<PackageTags>fable;fable-binding;fable-javascript</PackageTags>
136-
</PropertyGroup>
72+
<ItemGroup>
73+
<!-- Your F# code is already included because of the previous rules, so you only need to ensure the .js files are included as well -->
74+
<Content Include="**/*.js" Exclude="**\*.fs.js" PackagePath="fable/%(RelativeDir)%(Filename)%(Extension)" />
75+
</ItemGroup>
13776
```
13877

139-
If your package is a library which targets JavaScript and Python you need to write:
78+
:::info
79+
Note that you don't want to include Fable generated files and so we exclude them with `Exclude="**\*.fs.js"`
80+
:::
14081

141-
```xml
142-
<PropertyGroup>
143-
<PackageTags>fable;fable-library;fable-javascript;fable-python</PackageTags>
144-
</PropertyGroup>
145-
```
82+
In order to publish the package to Nuget check [the Microsoft documentation](https://docs.microsoft.com/en-us/nuget/quickstart/create-and-publish-a-package-using-the-dotnet-cli) or alternatively you can also [use Fake](https://fake.build/dotnet-nuget.html#Creating-NuGet-packages).
14683

147-
## Native dependencies
84+
### Native dependencies with Femto
14885

14986
When authoring a binding you often need your user to install a native dependency.
15087

@@ -177,6 +114,20 @@ For Python packages via poetry:
177114

178115
Please refer to [Femto documentation](https://github.com/Zaid-Ajaj/Femto) for more information.
179116

180-
## Testing
117+
### Testing
118+
119+
It's a good idea to write unit tests for your library to make sure everything works as expected before publishing.
120+
121+
Find below some libraries that can help you write tests for your Fable library:
122+
123+
- [Fable.Pyxpecto](https://github.com/Freymaurer/Fable.Pyxpecto): Inspired by the popular Expecto library for F#, Fable.Pyxpecto can be used to run tests in Python, JavaScript, TypeScript and .NET!
124+
- [Fable.Mocha](https://github.com/Zaid-Ajaj/Fable.Mocha): Fable library for testing. Inspired by the popular Expecto library for F# and adopts the testList, testCase and testCaseAsync primitives for defining tests.
125+
- Native runner like [Mocha](https://mochajs.org/), [example](https://github.com/fable-compiler/fable2-samples/tree/master/mocha).
126+
127+
### Listing
128+
129+
Once published to [NuGet](https://www.nuget.org/), your package will also be available on [Fable.Packages](https://fable.io/packages/) for easy discovery by the Fable community.
181130

182-
It's a good idea to write unit tests for your library to make sure everything works as expected before publishing. The simplest way for that is to use a JS test runner like [Mocha](https://mochajs.org/), as in [this sample](https://github.com/fable-compiler/fable2-samples/tree/master/mocha). Or you can also use a library like [Fable.Mocha](https://github.com/Zaid-Ajaj/Fable.Mocha) containing more tools for Fable projects.
131+
:::info
132+
This can take a few minutes to a few hours to be available on the website, depending on Nuget's indexing.
133+
:::

0 commit comments

Comments
 (0)