Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -489,4 +489,7 @@ tmp/
output/

# VSCode
.vscode/
.vscode/

# package lock file
package-lock.json
28 changes: 28 additions & 0 deletions hello-world/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

# regen each time
bun.lock
package.lock.json
24 changes: 24 additions & 0 deletions hello-world/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
## Hello World

### run

```
bun run dev
```

### build

```
bun run build
```

### preview

```
bun run preview
```


### latest?

`bun run archive` should generate and move the latest `vite-plugin-fable.x.y.z.tgz` into `/archive` folder, at this point you can run: `bun i` to install latest version of the library and test it out. if you want to cleanup `node_modules` and lock files, and instal the dep from scratch a utility script is provided `install-arch` as well.
488 changes: 488 additions & 0 deletions hello-world/bun.lock

Large diffs are not rendered by default.

Binary file added hello-world/lib/latest.tgz
Binary file not shown.
22 changes: 22 additions & 0 deletions hello-world/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "hello-world",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"archive": "cd .. && bun pm pack && cd hello-world && mkdir -p lib && mv ../*.tgz ./lib/latest.tgz",
"install-arch": "bun add ./lib/latest.tgz -d --trust",
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^6.2.0",
"vite-plugin-fable": "./lib/latest.tgz",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tgz seems weird, can't you use ../?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i tried but i had issues with recursion as it seems to install the whole univers in node_modules/vite-plugin-fable/...../node_modules/vite-plugin-fable.... and adding a bunch fo files even though they are not mentioned in files in root package.json, so i found this solution to be a bit better/slimmer and not having that recursive issue

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, yeah that is probably why I went with import plugin from "../index.js" instead.

"vitest": "^3.0.9"
},
"trustedDependencies": [
"esbuild",
"vite-plugin-fable"
]
}
19 changes: 19 additions & 0 deletions hello-world/src/App.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
<DisableImplicitFSharpCoreReference>false</DisableImplicitFSharpCoreReference>
</PropertyGroup>

<ItemGroup>
<Compile Include="Counter.fs" />
<Compile Include="Main.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Fable.Browser.Dom" Version="2.14.0" />
<PackageReference Include="Fable.Core" Version="4.3.0" />
Copy link
Collaborator Author

@jkone27 jkone27 Mar 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a regular fable / vite counter app with vanillajs

</ItemGroup>
</Project>
18 changes: 18 additions & 0 deletions hello-world/src/Counter.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Counter

open Browser.Dom
open Browser.Types

let setupCounter (element: Element) =

let mutable counter = 0

let setCounter count =
counter <- count
element.innerHTML <- $"count is {counter}"
printfn $"counter is: {counter}"
()

element.addEventListener("click", fun _ -> setCounter (counter + 1))

setCounter 0
1 change: 1 addition & 0 deletions hello-world/src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<Project></Project>
43 changes: 43 additions & 0 deletions hello-world/src/Main.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
module App

open Browser.Dom
open Fable.Core.JsInterop
open Counter

// Import CSS and SVG files
importSideEffects "./style.css"

let viteLogo: string = importDefault "./assets/vite.svg"

printfn $"{viteLogo}"

let javascriptLogo : string = importDefault "./javascript.svg"

printfn $"{javascriptLogo}"

// make html markup available using vscode F# html ext
let html = id

// Create the HTML content
let app = document.querySelector("#app")
app.innerHTML <-
html $"""
<div>
<a href="https://vite.dev" target="_blank">
<img src="{viteLogo}" class="logo" alt="Vite logo" />
</a>
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" target="_blank">
<img src="{javascriptLogo}" class="logo vanilla" alt="JavaScript logo" />
</a>
<h1>Hello Vite!</h1>
<div class="card">
<button id="counter" type="button"></button>
</div>
<p class="read-the-docs">
Click on the Vite logo to learn more
</p>
</div>
"""

document.querySelector("#counter")
|> Counter.setupCounter
1 change: 1 addition & 0 deletions hello-world/src/assets/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions hello-world/src/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="Main.fs"></script>
</body>
</html>
1 change: 1 addition & 0 deletions hello-world/src/javascript.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 96 additions & 0 deletions hello-world/src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}

h1 {
font-size: 3.2em;
line-height: 1.1;
}

#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vanilla:hover {
filter: drop-shadow(0 0 2em #f7df1eaa);
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
34 changes: 34 additions & 0 deletions hello-world/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineConfig } from 'vite';
import fable from 'vite-plugin-fable';
import { configDefaults } from 'vitest/config';

// https://nojaf.com/vite-plugin-fable/recipes.html#Using-React
// https://nojaf.com/vite-plugin-fable/recipes.html#Fable-Core-JSX

export default defineConfig({
// order of plugins matters, fable needs to be first
plugins: [
fable({
fsproj: "./src/App.fsproj"
}),
],
root: "./src",
build: {
outDir: "../dist",
sourcemap: 'inline'
},
define: {
// required if u have: `process is undefined`
// while loading react jsoncomponents
'process.env': {}
},
test: {
include: ['**/*.{test,spec}.{js,jsx,ts,tsx,fs}'],
exclude: [...configDefaults.exclude, 'dist', '.idea', '.git', '.cache'],
environment: 'jsdom',
setupFiles: '../vitest.ts',
transform: {
'^.+\\.fs$': 'vite-plugin-fable'
}
}
})
11 changes: 11 additions & 0 deletions hello-world/vitest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {
describe as vitestDescribe,
test as vitestTest,
expect as vitestExpect
} from 'vitest';

// Redirect Jest functions to Vitest
globalThis.describe = vitestDescribe;
globalThis.test = vitestTest;
globalThis.it = vitestTest; // Alias for `it` if used in tests
globalThis.expect = vitestExpect;