From 4440d6bad26d2ddaa85f0158c63e729ff1357e12 Mon Sep 17 00:00:00 2001 From: Maxime Mangel Date: Wed, 1 Nov 2023 21:43:38 +0100 Subject: [PATCH] Add new targets to the build system (compiler-js, package, etc.) --- .vscode/settings.json | 1 - build copy.fsx | 383 ----------------------------- src/Fable.Build/CompilerJs.fs | 5 +- src/Fable.Build/Fable.Build.fsproj | 7 +- src/Fable.Build/Main.fs | 28 ++- src/Fable.Build/Package.fs | 81 ++++++ src/Fable.Build/Publish.fs | 14 +- src/Fable.Build/Standalone.fs | 10 +- src/Fable.Build/Test/CompilerJs.fs | 50 ++++ src/Fable.Build/WorkerJs.fs | 62 +++++ src/Fable.Build/Workspace.fs | 2 + src/fable-standalone/CHANGELOG.md | 2 +- src/quicktest/QuickTest.fs | 2 + 13 files changed, 243 insertions(+), 404 deletions(-) delete mode 100644 build copy.fsx create mode 100644 src/Fable.Build/Package.fs create mode 100644 src/Fable.Build/Test/CompilerJs.fs create mode 100644 src/Fable.Build/WorkerJs.fs diff --git a/.vscode/settings.json b/.vscode/settings.json index c33642fdef..bc38a09f63 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,6 @@ "**/bin": true, "**/obj": true, "**/.fake": true, - "**/packages": true, "**/node_modules": true, "**/bower_components": true }, diff --git a/build copy.fsx b/build copy.fsx deleted file mode 100644 index 6ab551a2df..0000000000 --- a/build copy.fsx +++ /dev/null @@ -1,383 +0,0 @@ -#load "src/Fable.PublishUtils/PublishUtils.fs" - -open System -open System.Text.RegularExpressions -open PublishUtils - -// ncave FCS fork -let FCS_REPO = "https://github.com/ncave/fsharp" -let FCS_REPO_LOCAL = "../fsharp_fable" -let FCS_REPO_FABLE_BRANCH = "fable" -let FCS_REPO_SERVICE_SLIM_BRANCH = "service_slim" - -let BUILD_ARGS = - fsi.CommandLineArgs - |> Array.skip 1 - |> List.ofArray - -let BUILD_ARGS_LOWER = - BUILD_ARGS - |> List.map (fun x -> x.ToLower()) - -module Util = - let cleanDirs dirs = - for dir in dirs do - printfn $"Clean {dir}" - removeDirRecursive dir - - // TODO: move to PublishUtils.fs ? - let copyFiles sourceDir searchPattern destDir = - printfn $"Copy {sourceDir searchPattern} to {destDir}" - for source in IO.Directory.GetFiles(sourceDir, searchPattern) do - let fileName = IO.Path.GetFileName(source) - let target = destDir fileName - IO.File.Copy(source, target, true) - - let resolveDir dir = - __SOURCE_DIRECTORY__ dir - - let updateVersionsInFableTransforms compilerVersion (libraryVersions: (string * string) list) = - let mutable updated = Set.empty - - let replaceVersion (lang: string option) version fileContent = - let prefix = - match lang with - | None -> "" - | Some lang -> $"{lang.ToUpperInvariant()}_LIBRARY_" - - Regex.Replace( - fileContent, - $@"^(\s*)let \[] {prefix}VERSION = ""(.*?)""", - (fun (m: Match) -> - match lang with - | Some lang when m.Groups[2].Value <> version -> - updated <- Set.add lang updated - | _ -> () - m.Groups[1].Value + $"let [] {prefix}VERSION = \"{version}\"" - ), - RegexOptions.Multiline) - - let filePath = "src/Fable.Transforms/Global/Compiler.fs" - readFile filePath - |> replaceVersion None compilerVersion - |> List.foldBack (fun (lang, version) fileContent -> - replaceVersion (Some lang) version fileContent) libraryVersions - |> writeFile filePath - - updated - - let updatePkgVersionInFsproj projFile version = - readFile projFile - |> replaceRegex Publish.NUGET_PACKAGE_VERSION (fun m -> - m.Groups[1].Value + version + m.Groups[3].Value) - |> writeFile projFile - - let runTSLint projectDir = - run ("npm run tslint -- --project " + projectDir) - - let runTypeScript projectDir = - run ("npm run tsc -- --project " + projectDir) - - let runTypeScriptWithArgs projectDir args = - run ("npm run tsc -- --project " + projectDir + " " + String.concat " " args) - - let runFableWithArgs projectDir args = - run ("dotnet run -c Release --project src/Fable.Cli -- " + projectDir + " " + String.concat " " args) - - let watchFableWithArgs projectDir args = - run ("dotnet watch --project src/Fable.Cli run -- " + projectDir + " --cwd ../.. " + String.concat " " args) - - let runFableWithArgsInDirAs release projectDir args = - let cliDir = resolveDir "src/Fable.Cli" - let cliArgs = args |> String.concat " " - let cliCmd = $"""dotnet run {if release then "-c Release" else ""} --project {cliDir} -- {cliArgs}""" - runInDir (resolveDir projectDir) cliCmd - - let runFableWithArgsInDir projectDir args = - runFableWithArgsInDirAs true projectDir args - - let runFableWithArgsAsync projectDir args = - runAsync ("dotnet run -c Release --project src/Fable.Cli -- " + projectDir + " " + String.concat " " args) - - let runNpx command args = - run ("npx " + command + " " + (String.concat " " args)) - - let runNpmScript script args = - run ("npm run " + script + " -- " + (String.concat " " args)) - - let runNpmScriptAsync script args = - runAsync ("npm run " + script + " -- " + (String.concat " " args)) - - let runFable projectDir = - runFableWithArgs projectDir [] - - let runMocha testDir = - runNpmScript "mocha" [$"{testDir} --reporter dot -t 10000"] - -open Util - -module Unused = - let downloadAndExtractTo (url: string) (targetDir: string) = - $"npx download --extract --out %s{targetDir} \"%s{url}\"" |> run - - let coverage() = - // report converter - // https://github.com/danielpalme/ReportGenerator - // dotnet tool install dotnet-reportgenerator-globaltool --tool-path tools - if not (pathExists "./bin/tools/reportgenerator") && not (pathExists "./bin/tools/reportgenerator.exe") then - runInDir "." "dotnet tool install dotnet-reportgenerator-globaltool --tool-path bin/tools" - let reportGen = - if pathExists "./bin/tools/reportgenerator" then "bin/tools/reportgenerator" - else "bin\\tools\\reportgenerator.exe" - - // if not (pathExists "build/fable-library") then - // buildLibrary() - - cleanDirs ["build/tests"] - runFable "tests" - - // JS - run "npx nyc mocha build/tests --require source-map-support/register --reporter dot -t 10000" - runInDir "." (reportGen + " \"-reports:build/coverage/nyc/lcov.info\" -reporttypes:Html \"-targetdir:build/coverage/nyc/html\" ") - - // .NET - //runInDir "tests/Main" "dotnet build /t:Collect_Coverage" - cleanDirs ["build/coverage/netcoreapp2.0/out"] - runInDir "." (reportGen + " \"-reports:build/coverage/netcoreapp2.0/coverage.xml\" -reporttypes:Html \"-targetdir:build/coverage/netcoreapp2.0/html\" ") - - - -let buildWorker (opts: {| minify: bool; watch: bool |}) = - printfn "Building worker%s..." (if opts.minify then "" else " (no minification)") - - let projectDir = "src/fable-standalone/src" - let buildDir = "build/fable-standalone" - let distDir = "src/fable-standalone/dist" - - runFableWithArgs (projectDir + "/Worker") [ - "--outDir " + buildDir + "/worker" - ] - - let rollupTarget = - match opts.minify with - | true -> buildDir "worker.js" - | false -> distDir "worker.min.js" - - // make standalone worker dist - runNpmScript "rollup" [$"""{buildDir}/worker/Worker.js -o {rollupTarget} --format iife"""] - - if opts.minify then - // runNpx "webpack" [sprintf "--entry ./%s/worker.js --output ./%s/worker.min.js --config ./%s/../worker.config.js" buildDir distDir projectDir] - runNpmScript "terser" [$"{buildDir}/worker.js -o {distDir}/worker.min.js --mangle --compress"] - - // Put fable-library files next to bundle - printfn "Copying fable-library..." - // buildLibraryTsIfNotExists() - let libraryDir = "build/fable-library" - let libraryTarget = distDir "fable-library" - copyDirRecursive libraryDir libraryTarget - -let buildStandalone (opts: {| minify: bool; watch: bool |}) = - // buildLibraryTs() - - printfn "Building standalone%s..." (if opts.minify then "" else " (no minification)") - - let projectDir = "src/fable-standalone/src" - let buildDir = "build/fable-standalone" - let distDir = "src/fable-standalone/dist" - - let rollupTarget = - match opts.watch, opts.minify with - | true, _ -> - match BUILD_ARGS with - | _::rollupTarget::_ -> rollupTarget - | _ -> failwith "Pass the bundle output, e.g.: npm run build watch-standalone ../repl3/public/js/repl/bundle.min.js" - | false, true -> buildDir "bundle.js" - | false, false -> distDir "bundle.min.js" - - let rollupArgs = [ - buildDir "bundle/Main.js" - "-o " + rollupTarget - "--format umd" - "--name __FABLE_STANDALONE__" - ] - - // cleanup - if not opts.watch then - cleanDirs [buildDir; distDir] - makeDirRecursive distDir - - // build standalone bundle - runFableWithArgs projectDir [ - "--outDir " + buildDir "bundle" - if opts.watch then - "--watch" - "--run rollup" - yield! rollupArgs - "--watch" - ] - - // make standalone bundle dist - runNpmScript "rollup" rollupArgs - if opts.minify then - runNpmScript "terser" [ - buildDir "bundle.js" - "-o " + distDir "bundle.min.js" - "--mangle" - "--compress" - ] - - // build standalone worker - buildWorker opts - - // print bundle size - fileSizeInBytes (distDir "bundle.min.js") / 1000. |> printfn "Bundle size: %fKB" - fileSizeInBytes (distDir "worker.min.js") / 1000. |> printfn "Worker size: %fKB" - -let buildCompilerJs(minify: bool) = - let projectDir = "src/fable-compiler-js/src" - let buildDir = "build/fable-compiler-js" - let distDir = "src/fable-compiler-js/dist" - - if not (pathExists "build/fable-standalone") then - buildStandalone {|minify=minify; watch=false|} - - cleanDirs [buildDir; distDir] - makeDirRecursive distDir - - runFableWithArgs projectDir [ - "--outDir " + buildDir - "--exclude Fable.Core" - ] - - let rollupTarget = if minify then distDir "app.js" else distDir "app.min.js" - run $"npx rollup {buildDir}/app.js -o {rollupTarget} --format umd --name Fable" - if minify then - run $"npx terser {distDir}/app.js -o {distDir}/app.min.js --mangle --compress" - - // Copy fable-library - copyDirRecursive ("build/fable-library") (distDir "fable-library") - // Copy fable-metadata - copyDirRecursive ("src/fable-metadata/lib") (distDir "fable-metadata") - -let testStandalone(minify) = - let fableDir = "src/fable-compiler-js" - let buildDir = "build/tests/Standalone" - - if not (pathExists "build/fable-compiler-js") then - buildCompilerJs(minify) - - cleanDirs [buildDir] - - // Link fable-compiler-js to local packages - runInDir fableDir "npm link ../fable-metadata" - runInDir fableDir "npm link ../fable-standalone" - - // Test fable-compiler-js locally - run $"node {fableDir} tests/Js/Main/Fable.Tests.fsproj {buildDir}" - runMocha buildDir - - // // Another local fable-compiler-js test - // runInDir (fableDir "test") "node .. test_script.fsx" - // runInDir (fableDir "test") "node test_script.fsx.js" - - // Unlink local packages after test - runInDir fableDir "npm unlink ../fable-metadata && cd ../fable-metadata && npm unlink" - runInDir fableDir "npm unlink ../fable-standalone && cd ../fable-standalone && npm unlink" - -let buildLocalPackageWith pkgDir pkgCommand fsproj action = - let version = Publish.loadReleaseVersion "src/Fable.Cli" + "-local-build-" + DateTime.Now.ToString("yyyyMMdd-HHmm") - action version - updatePkgVersionInFsproj fsproj version - run $"dotnet pack {fsproj} -p:Pack=true -c Release -o {pkgDir}" - - // Return install command - $"""dotnet {pkgCommand} --version "{version}" --add-source {fullPath pkgDir}""" - -let buildLocalPackage pkgDir = - buildLocalPackageWith pkgDir - "tool install fable" - (resolveDir "src/Fable.Cli/Fable.Cli.fsproj") (fun version -> - updateVersionsInFableTransforms version [] |> ignore - // buildLibraryTs() - ) - -let testRepos() = - let repos = [ - "https://github.com/alfonsogarciacaro/FsToolkit.ErrorHandling:update-fable-3", "npm i && npm test" - "https://github.com/fable-compiler/fable-promise:master", "npm i && npm test" - "https://github.com/alfonsogarciacaro/Thoth.Json:nagareyama", "dotnet paket restore && npm i && dotnet fable tests -o tests/bin --run mocha tests/bin" - "https://github.com/alfonsogarciacaro/FSharp.Control.AsyncSeq:nagareyama", "cd tests/fable && npm i && npm test" - "https://github.com/alfonsogarciacaro/Fable.Extras:nagareyama", "dotnet paket restore && npm i && npm test" - "https://github.com/alfonsogarciacaro/Fable.Jester:nagareyama", "npm i && npm test" - "https://github.com/Zaid-Ajaj/Fable.SimpleJson:master", "npm i && npm run test-nagareyama" - ] - - let testDir = tempPath() "fable-repos" - printfn $"Cloning repos to: {testDir}" - - cleanDirs [testDir] - makeDirRecursive testDir - let pkgInstallCmd = buildLocalPackage (testDir "pkg") - - for (repo, command) in repos do - let url, branch = let i = repo.LastIndexOf(":") in repo[..i-1], repo[i+1..] - let name = url[url.LastIndexOf("/") + 1..] - runInDir testDir $"git clone {url} {name}" - let repoDir = testDir name - runInDir repoDir ("git checkout " + branch) - runInDir repoDir "dotnet tool uninstall fable" - runInDir repoDir pkgInstallCmd - runInDir repoDir "dotnet tool restore" - runInDir repoDir command - - -let hasFlag flag = - BUILD_ARGS_LOWER |> List.contains flag - -match BUILD_ARGS_LOWER with -// | "check-sourcemaps"::_ -> -// ("src/quicktest/Quicktest.fs", "src/quicktest/bin/Quicktest.js", "src/quicktest/bin/Quicktest.js.map") -// |||> sprintf "nodemon --watch src/quicktest/bin/Quicktest.js --exec 'source-map-visualization --sm=\"%s;%s;%s\"'" -// |> List.singleton |> quicktest -// | "coverage"::_ -> coverage() - -// | "test-standalone-fast"::_ -> testStandaloneFast() -| "test-repos"::_ -> testRepos() - -| "package"::_ -> - let pkgInstallCmd = buildLocalPackage (resolveDir "temp/pkg") - printfn $"\nPackage has been created, use the following command to install it:\n {pkgInstallCmd}\n" -| "package-core"::_ -> - let pkgInstallCmd = buildLocalPackageWith (resolveDir "temp/pkg") "add package Fable.Core" (resolveDir "src/Fable.Core/Fable.Core.fsproj") ignore - printfn $"\nFable.Core package has been created, use the following command to install it:\n {pkgInstallCmd}\n" - -| ("fable-compiler-js"|"compiler-js")::_ -> - let minify = hasFlag "--no-minify" |> not - buildCompilerJs(minify) -| ("fable-standalone"|"standalone")::_ -> - let minify = hasFlag "--no-minify" |> not - buildStandalone {|minify=minify; watch=false|} -| ("fable-worker"|"worker")::_ -> - let minify = hasFlag "--no-minify" |> not - buildWorker {|minify=minify; watch=false|} -| "watch-standalone"::_ -> buildStandalone {|minify=false; watch=true|} - - -| _ -> - printfn """Please pass a target name. Examples: - -- Use `test` to run tests: - dotnet fsi build.fsx test - -- Use `package` to build a local package: - dotnet fsi build.fsx package - -- Use `run` to compile a project with development version: - dotnet fsi build.fsx run ../path/to/my/project [Fable options] - -- Use `quicktest` to quickly test development version with src/quicktest project: - dotnet fsi build.fsx quicktest -""" - -printfn "Build finished successfully" diff --git a/src/Fable.Build/CompilerJs.fs b/src/Fable.Build/CompilerJs.fs index 45f61ffdc1..7c7c49a604 100644 --- a/src/Fable.Build/CompilerJs.fs +++ b/src/Fable.Build/CompilerJs.fs @@ -9,9 +9,6 @@ open Build open SimpleExec open Fake.IO -let private mainTestProject = - Path.Resolve("tests", "Js", "Main", "Fable.Tests.fsproj") - let private fableCompilerJsDir = Path.Resolve("src", "fable-compiler-js") let private buildDir = Path.Combine(fableCompilerJsDir, "temp") let private distDir = Path.Combine(fableCompilerJsDir, "dist") @@ -32,7 +29,7 @@ let handle (args: string list) = // We don't need to build fable-library, because it will be // build as part of Standalone.build - Standalone.build minify + Standalone.handle args // Clean up temp folders Directory.clean buildDir diff --git a/src/Fable.Build/Fable.Build.fsproj b/src/Fable.Build/Fable.Build.fsproj index 442893af0b..73aa2468a9 100644 --- a/src/Fable.Build/Fable.Build.fsproj +++ b/src/Fable.Build/Fable.Build.fsproj @@ -19,6 +19,9 @@ + + + @@ -26,17 +29,17 @@ + - - + diff --git a/src/Fable.Build/Main.fs b/src/Fable.Build/Main.fs index ee4c5c71a0..f09ce71441 100644 --- a/src/Fable.Build/Main.fs +++ b/src/Fable.Build/Main.fs @@ -57,13 +57,33 @@ Available commands: --no_std Compile and run the tests without the standard library --threaded Compile and run the tests with the threaded runtime - standalone Compile standalone version of Fable running + standalone Compile standalone + worker version of Fable running on top of of Node.js Options: + --skip-fable-library Skip building fable-library if folder already exists --no-minify Don't minify the JavaScript output --watch Watch for changes and recompile + worker-js Compile the worker for the standalone version of Fable + + Options: + --skip-fable-library Skip building fable-library if folder already exists + --no-minify Don't minify the JavaScript output + + compiler-js Compile the Fable compiler to JavaScript + + Options: + --skip-fable-library Skip building fable-library if folder already exists + --no-minify Don't minify the JavaScript output + + package Generate local package for Fable.Cli and Fable.Core + allowing to use this local package for testing + inside of other projects + + Options: + --skip-fable-library Skip building fable-library if folder already exists + publish Publish the different packages to NuGet and NPM based on the CHANGELOG.md files If the last version in the CHANGELOG.md is @@ -99,6 +119,9 @@ let main argv = | "rust" :: args -> Test.Rust.handle args | "integration" :: args -> Test.Integration.handle args | "standalone" :: _ -> Test.Standalone.handle args + // This test is using quicktest project for now, + // because it can't compile (yet?) the Main JavaScript tests + | "compiler-js" :: _ -> Test.CompilerJs.handle args | _ -> printHelp () | "quicktest" :: args -> match args with @@ -110,10 +133,13 @@ let main argv = | _ -> printHelp () | "standalone" :: args -> Standalone.handle args | "compiler-js" :: args -> CompilerJs.handle args + | "worker-js" :: args -> WorkerJs.handle args | "sync-fcs-repo":: _ -> FcsRepo.sync () | "copy-fcs-repo":: _ -> FcsRepo.copy () | "publish" :: args -> Publish.handle args | "github-release" :: args -> GithubRelease.handle args + | "package" :: args -> Package.handle args + | "help" :: _ | "--help" :: _ | _ -> printHelp () diff --git a/src/Fable.Build/Package.fs b/src/Fable.Build/Package.fs new file mode 100644 index 0000000000..6d8f43ccbd --- /dev/null +++ b/src/Fable.Build/Package.fs @@ -0,0 +1,81 @@ +module Build.Package + +open Build.Utils +open Build.FableLibrary +open Octokit +open System +open Build.Workspace +open SimpleExec +open BlackFox.CommandLine +open System.IO + +let private packageDestination = Path.Resolve("temp", "packages") + +let handle (args: string list) = + let skipFableLibrary = args |> List.contains "--skip-fable-library" + // Build all the fable-libraries + BuildFableLibraryDart().Run(skipFableLibrary) + BuildFableLibraryJavaScript().Run(skipFableLibrary) + BuildFableLibraryPython().Run(skipFableLibrary) + BuildFableLibraryRust().Run(skipFableLibrary) + BuildFableLibraryTypeScript().Run(skipFableLibrary) + + Directory.clean packageDestination + + let fableCliVersionInfo = Changelog.getLastVersion Changelog.fableCLi + + let fableCliVersion = + fableCliVersionInfo.Version.ToString() + + "-local-build-" + + DateTime.Now.ToString("yyyyMMdd-HHhmm") + + let compilerFsPath = + Path.Resolve("src", "Fable.Transforms", "Global", "Compiler.fs") + + let compilerFsOriginalContent = File.ReadAllText compilerFsPath + + Publish.updateLibraryVersionInFableTransforms fableCliVersion {| + JavaScript = Npm.getVersionFromProjectDir ProjectDir.temp_fable_library + |} + + Command.Run( + "dotnet", + CmdLine.empty + |> CmdLine.appendRaw "pack" + |> CmdLine.appendRaw Fsproj.fableCli + |> CmdLine.appendPrefix "-c" "Release" + // By pass the PackageVersion in the fsproj, without having to modify it on the disk + |> CmdLine.appendRaw $"-p:PackageVersion={fableCliVersion}" + |> CmdLine.appendPrefix "-o" packageDestination + |> CmdLine.toString + ) + + // This avoid common error of comitting the modified file + File.WriteAllText(compilerFsPath, compilerFsOriginalContent) + + let fableCoreVersionInfo = Changelog.getLastVersion Changelog.fableCore + + let fableCoreVersion = + fableCoreVersionInfo.Version.ToString() + + "-local-build-" + + DateTime.Now.ToString("yyyyMMdd-HHhmm") + + Command.Run( + "dotnet", + CmdLine.empty + |> CmdLine.appendRaw "pack" + |> CmdLine.appendRaw Fsproj.fableCore + |> CmdLine.appendPrefix "-c" "Release" + // By pass the PackageVersion in the fsproj, without having to modify it on the disk + |> CmdLine.appendRaw $"-p:PackageVersion={fableCoreVersion}" + |> CmdLine.appendPrefix "-o" packageDestination + |> CmdLine.toString + ) + + printfn $"""Local packages created. + +Use the following commands to install them: + +- Fable.Cli: dotnet tool update fable --version {fableCliVersion} --add-source {packageDestination} +- Fable.Core: dotnet add package Fable.Core --version {fableCoreVersion} --add-source {packageDestination} + """ diff --git a/src/Fable.Build/Publish.fs b/src/Fable.Build/Publish.fs index 4df773d4cd..258d6e5bee 100644 --- a/src/Fable.Build/Publish.fs +++ b/src/Fable.Build/Publish.fs @@ -7,7 +7,7 @@ open Build.FableLibrary open System open Build.Workspace -let private updateLibraryVersionInFableTransforms +let updateLibraryVersionInFableTransforms (compilerVersion: string) (librariesVersion: {| JavaScript: string |}) = @@ -129,7 +129,10 @@ let handle (args: string list) = // For fable-library, we use the compiled version of the project for publishing // This i because we want to publish the JavaScript code and not a mix of F# and TypeScript + // Disabled because only Alfonso can publish fable-library + // I requested to NPM/Github to give me access to the package, still waiting for an answer publishNpm ProjectDir.temp_fable_library + // We need also want to update the original package.json if needed // This is to keep the versions consistent across the project // and also will be used when updating libraries version inside of Fable compiler @@ -138,12 +141,11 @@ let handle (args: string list) = publishNpm ProjectDir.fable_metadata // Disabled because standalone terser optimisation seems to never end - // Standalone.handle [] - // publishNpm ProjectDir.fable_standalone + Standalone.handle [] + publishNpm ProjectDir.fable_standalone - // Disabled as we need standalone - // TODO: Build fable compiler js - // publishNpm ProjectDir.fable_compiler_js + CompilerJs.handle [] + publishNpm ProjectDir.fable_compiler_js // Update embedded version (both compiler and libraries) let changelogPath = Path.Combine(ProjectDir.fableCli, "CHANGELOG.md") diff --git a/src/Fable.Build/Standalone.fs b/src/Fable.Build/Standalone.fs index 33c468bad1..96f0634a12 100644 --- a/src/Fable.Build/Standalone.fs +++ b/src/Fable.Build/Standalone.fs @@ -88,7 +88,9 @@ let build (minify: bool) = |> CmdLine.appendRaw "rollup" |> CmdLine.appendRaw (buildDir "Main.js") |> CmdLine.appendPrefix "-o" (buildDir "bundle.js") - |> CmdLine.appendPrefix "--format" "esm" + // We need to use umd format so it can be used inside of web workers + // Web workers don't support ES modules (yet) + |> CmdLine.appendPrefix "--format" "umd" |> CmdLine.appendPrefix "--name" "__FABLE_STANDALONE__" |> CmdLine.toString, workingDirectory = projectDir @@ -106,13 +108,9 @@ let build (minify: bool) = workingDirectory = projectDir ) - buildWorker minify - let handle (args: string list) = let minify = args |> List.contains "--no-minify" |> not let isWatch = args |> List.contains "--watch" - let skipFableLibrary = args |> List.contains "--skip-fable-library" - - BuildFableLibraryJavaScript().Run(skipFableLibrary) build minify + WorkerJs.handle args diff --git a/src/Fable.Build/Test/CompilerJs.fs b/src/Fable.Build/Test/CompilerJs.fs new file mode 100644 index 0000000000..759c4329cf --- /dev/null +++ b/src/Fable.Build/Test/CompilerJs.fs @@ -0,0 +1,50 @@ +module Build.Test.CompilerJs + + +open Build.FableLibrary +open System.IO +open Build.Utils +open BlackFox.CommandLine +open SimpleExec +open Fake.IO + +let private fableCompilerJsDir = Path.Resolve("src", "fable-compiler-js") + +let private quicktestProject = + Path.Resolve("src", "quicktest", "Quicktest.fsproj") + +let private quicktestBuildDir = + Path.Resolve("temp", "tests", "fable-compiler-js", "quicktest") + +let handle (args : string list) = + Command.Run( + "npm", + "link ../fable-standalone ../fable-metadata", + workingDirectory = fableCompilerJsDir + ) + + Build.CompilerJs.handle args + + Command.Run( + "node", + CmdLine.empty + |> CmdLine.appendRaw "index.js" + |> CmdLine.appendRaw quicktestProject + |> CmdLine.appendPrefix "--outDir" quicktestBuildDir + |> CmdLine.toString, + workingDirectory = fableCompilerJsDir + ) + + Command.Run( + "node", + quicktestBuildDir "QuickTest.js", + workingDirectory = fableCompilerJsDir + ) + + // TODO: Add test against an fsx file but for now it seems broken + + Command.Run( + "npm", + "unlink ../fable-standalone ../fable-metadata", + workingDirectory = fableCompilerJsDir + ) diff --git a/src/Fable.Build/WorkerJs.fs b/src/Fable.Build/WorkerJs.fs new file mode 100644 index 0000000000..cd3c05007f --- /dev/null +++ b/src/Fable.Build/WorkerJs.fs @@ -0,0 +1,62 @@ +module Build.WorkerJs + +open SimpleExec +open Build.Utils +open BlackFox.CommandLine +open System.IO +open Build.FableLibrary +open Fake.IO + +let private projectDir = Path.Resolve("src", "fable-standalone") + +let private buildDir = Path.Combine(projectDir, "temp") + +let private distDir = Path.Combine(projectDir, "dist") + +let handle (args: string list) = + let minify = args |> List.contains "--no-minify" |> not + let skipFableLibrary = args |> List.contains "--skip-fable-library" + + BuildFableLibraryJavaScript().Run(skipFableLibrary) + + let fableArgs = + CmdLine.empty + |> CmdLine.appendRaw "src/Worker" + |> CmdLine.appendPrefix "--outDir" (buildDir "worker") + |> CmdLine.appendPrefix "--lang" "javascript" + + Command.Fable(fableArgs, workingDirectory = projectDir) + + Command.Run( + "npx", + CmdLine.empty + |> CmdLine.appendRaw "rollup" + |> CmdLine.appendRaw (buildDir "worker" "Worker.js") + |> CmdLine.appendPrefix "-o" (buildDir "worker" "bundle.js") + |> CmdLine.appendPrefix "--format" "iife" + |> CmdLine.toString, + workingDirectory = projectDir + ) + + Command.Run( + "npx", + CmdLine.empty + |> CmdLine.appendRaw "esbuild" + |> CmdLine.appendRaw (buildDir "worker" "bundle.js") + |> CmdLine.appendRaw $"""--outfile={(distDir "worker.min.js")}""" + |> CmdLine.appendRaw "--format=iife" + |> CmdLine.appendIf minify "--minify" + |> CmdLine.toString, + workingDirectory = projectDir + ) + + let fableLibraryDist = (distDir "fable-library") + + Directory.ensure fableLibraryDist + + // Copy Fable library to dist folder + Shell.copyRecursive + (Path.Resolve("temp", "fable-library")) + fableLibraryDist + true + |> ignore diff --git a/src/Fable.Build/Workspace.fs b/src/Fable.Build/Workspace.fs index 4297e974c4..0e4978e770 100644 --- a/src/Fable.Build/Workspace.fs +++ b/src/Fable.Build/Workspace.fs @@ -20,7 +20,9 @@ module ProjectDir = module Fsproj = let fableCli = Path.Combine(ProjectDir.fableCli, "Fable.Cli.fsproj") + let fableCore = Path.Combine(ProjectDir.fableCore, "Fable.Core.fsproj") module Changelog = let fableCLi = Path.Combine(ProjectDir.fableCli, "CHANGELOG.md") + let fableCore = Path.Combine(ProjectDir.fableCore, "CHANGELOG.md") diff --git a/src/fable-standalone/CHANGELOG.md b/src/fable-standalone/CHANGELOG.md index f94d076db2..c6ca1ae430 100644 --- a/src/fable-standalone/CHANGELOG.md +++ b/src/fable-standalone/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased -* Use ESM format +* Use ESM syntax but still publish to UMD * Remove `--typescript` options support, use `--lang ` instead ## 3.2.11 diff --git a/src/quicktest/QuickTest.fs b/src/quicktest/QuickTest.fs index 9d5fcc047f..4c483eab14 100644 --- a/src/quicktest/QuickTest.fs +++ b/src/quicktest/QuickTest.fs @@ -74,6 +74,8 @@ let measureTime (f: unit -> unit): unit = emitJsStatement () """ //!js """ +printfn "Running quick tests..." + // Write here your unit test, you can later move it // to Fable.Tests project. For example: // testCase "Addition works" <| fun () ->