Skip to content

Instantly share code, notes, and snippets.

@maestrow
Last active March 8, 2018 20:58
Show Gist options
  • Select an option

  • Save maestrow/70ed3fcee7127cac9b860923ea5e76a2 to your computer and use it in GitHub Desktop.

Select an option

Save maestrow/70ed3fcee7127cac9b860923ea5e76a2 to your computer and use it in GitHub Desktop.
Fable technology stack

Create Fable Application manually from scratch

Для создания проекта fable в dotnet core доступен специальный шаблон. Установить его можно командой dotnet new -i Fable.Template. А создать новое приложение по данному шаблону можно командой dotnet new fable -n FableApp -lang F# -o . (FableApp - имя проекта; -o - путь к папке проекта, по умолчанию текущая директория).

В данной статье рассматривается инструкция по созданию такого шаблона (каркаса приложения fable) с нуля, что поможет разобраться в архитектуре Fable.

Prerequisites

Create app folder

powershell
mkdir fable-from-scratch
cd .\fable-from-scratch

Bootstrap paket

Refer to automation script or do it manually.

Download fresh paket version:

$env:Path += ";./.paket"
$html = Invoke-WebRequest -Uri "https://github.com/fsprojects/Paket/releases/latest"
$href = $html.ParsedHtml.getElementsByTagName("a") | where { $_.href -Like "*paket.bootstrapper.exe" } | select -ExpandProperty href | select -Unique
$url = $href -replace "about:/", "https://github.com/"

(New-Object System.Net.WebClient).DownloadFile($url, "$pwd/.paket/paket.exe")

Then init:

paket init
"storage: none" | Add-Content "paket.dependencies"

Create F# lib

dotnet new classlib -n FableFromScratch -lang f# -o src

Add packages

paket add Fable.Core --project .\src\FableFromScratch.fsproj
paket add Fable.Import.Browser --project .\src\FableFromScratch.fsproj

To see all fable packages: paket find-packages Fable To add package only to specific project: paket add Fable.Core --project .\src\FableFromScratch.fsproj

Add fable cli tool

paket add dotnet-fable -t clitool --project .\src\FableFromScratch.fsproj

Add nodejs packages

yarn init -y
yarn add -D babel-core babel-loader babel-preset-env fable-loader fable-utils webpack webpack-dev-server

Then add scripts block to package.json. After that package.json must looks like:

{
  "private": true,
  "scripts": {
    "build": "webpack -p",
    "start": "webpack-dev-server",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "babel-core": "6.26.0",
    "babel-loader": "7.1.2",
    "babel-preset-env": "1.6.1",
    "fable-loader": "1.1.6",
    "fable-utils": "1.0.6",
    "webpack": "3.8.1",
    "webpack-dev-server": "2.9.4"
  }
}

If you prefere to create package.json manually, then after that you should run yarn install to install packages.

Webpack

Add webpack.config.js to your project root:

var path = require("path");
var webpack = require("webpack");
var fableUtils = require("fable-utils");

function resolve(filePath) {
  return path.join(__dirname, filePath)
}

var babelOptions = fableUtils.resolveBabelOptions({
  presets: [
    ["env", {
      "targets": {
        "browsers": "> 1%"
      },
      "modules": false
    }]
  ],
});

var isProduction = process.argv.indexOf("-p") >= 0;
console.log("Bundling for " + (isProduction ? "production" : "development") + "...");

module.exports = {
  devtool: "source-map",
  entry: resolve('./src/FableFromScratch.fsproj'),
  output: {
    filename: 'bundle.js',
    path: resolve('./public'),
  },
  resolve: {
    modules: [resolve("./node_modules/")]
  },
  devServer: {
    contentBase: resolve('./public'),
    port: 8080
  },
  module: {
    rules: [
      {
        test: /\.fs(x|proj)?$/,
        use: {
          loader: "fable-loader",
          options: {
            babel: babelOptions,
            define: isProduction ? [] : ["DEBUG"]
          }
        }
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: babelOptions
        },
      }
    ]
  }
};

Then:

cd src
dotnet fable yarn-run start

Open your browser at http://localhost:8080. Source maps must be available.

Fable technology stack

Технологии:

  • Dotnet CLI
  • Paket
  • Fake

Live reload

dotnet watch run

https://docs.microsoft.com/en-us/aspnet/core/tutorials/dotnet-watch

Команда dotnet watch становится доступной после добавления в *.fsproj строчки:

<ItemGroup>
  <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" />
</ItemGroup> 

Fable-Elmish

https://fable-elmish.github.io

Side notes

  • Is it a bug, if I had to change <TargetFramework>netstandard1.6</TargetFramework> to <TargetFramework>netcoreapp1.1</TargetFramework> in fsproj after it was generated by dotnet new fable -n MyProject? If I didn't do that, I've got dotnet-fable that has not yarn-... commands (but only npm-... commands).
  • fable-elmish-snabbdom теперь deprecated - elmish/elmish#62.

Quick start

Как создать новый проект написано в статье Getting Started

Для создания проектов fable и fable-elmish с помощью dotnet CLI можно воспользоваться шаблонами. Установка шаблонов:

dotnet new -i Fable.Template
dotnet new -i Fable.Template.Elmish.React

dotnet new -i SAFE.Template

Создайте пустую директорию. В пути не должно присутствовать восклицательных знаков (см. webpack/webpack#4906) и символов "-" (также проблемы с webpack). Команды для генерации пустого проекта по шаблону:

dotnet new fable
dotnet new fable-elmish-react

dotnet new SAFE -lang F#

Для запуска выполните инструкции из readme.md:

yarn install
dotnet restore
dotnet fable npm-run start

Последняя команда запускает локальный веб-сервер по адресу http:\localhost:8080 с функцией live-reload.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment