diff --git a/.gitignore b/.gitignore index 5e9d92cf5d..667ee11eb9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ node_modules/ temp/ *.fs.js +*.fs.js.map src/fable-library/*.js src/fable-library/BigInt/*.js diff --git a/src/Fable.Cli/Entry.fs b/src/Fable.Cli/Entry.fs index 99c3aeba6c..5c14866b7e 100644 --- a/src/Fable.Cli/Entry.fs +++ b/src/Fable.Cli/Entry.fs @@ -53,6 +53,7 @@ Arguments: --cwd Working directory -o|--outDir Redirect compilation output to a directory --extension Extension for generated JS files (default .fs.js) + -s|--sourceMaps Enable source maps --define Defines a symbol for use in conditional compilation --verbose Print more info during compilation @@ -159,6 +160,7 @@ type Runner = FableLibraryPath = argValue "--fableLib" args RootDir = rootDir OutDir = argValueMulti ["-o"; "--outDir"] args |> Option.map normalizeAbsolutePath + SourceMaps = flagEnabled "-s" args || flagEnabled "--sourceMaps" args ForcePkgs = flagEnabled "--forcePkgs" args NoRestore = flagEnabled "--noRestore" args Exclude = argValue "--exclude" args @@ -190,7 +192,7 @@ let clean args dir = argValue "--extension" args |> Option.defaultValue (defaultFileExt typescript args) // clean is a potentially destructive operation, we need a permission before proceeding - Console.WriteLine("This will recursively delete all *{0} files in {1}", fileExt, dir) + Console.WriteLine("This will recursively delete all *{0}[.map] files in {1}", fileExt, dir) if not(flagEnabled "--yes" args) then Console.WriteLine("Please press 'Y' or 'y' if you want to continue: ") let keyInfo = Console.ReadKey() @@ -201,8 +203,11 @@ let clean args dir = let mutable fileCount = 0 let rec recClean dir = - IO.Directory.GetFiles(dir, "*" + fileExt) - |> Array.iter (fun file -> + seq { + yield! IO.Directory.GetFiles(dir, "*" + fileExt) + yield! IO.Directory.GetFiles(dir, "*" + fileExt + ".map") + } + |> Seq.iter (fun file -> IO.File.Delete(file) fileCount <- fileCount + 1 Log.verbose(lazy ("Deleted " + file))) diff --git a/src/Fable.Cli/Fable.Cli.fsproj b/src/Fable.Cli/Fable.Cli.fsproj index 849d0cef0a..dde3652be3 100644 --- a/src/Fable.Cli/Fable.Cli.fsproj +++ b/src/Fable.Cli/Fable.Cli.fsproj @@ -3,8 +3,8 @@ Exe netcoreapp3.1 - 3.0.5 - 3.0.5 + 3.1.0 + 3.1.0-beta-001 Major true @@ -37,6 +37,7 @@ + diff --git a/src/Fable.Cli/Main.fs b/src/Fable.Cli/Main.fs index 97cde04872..8b5227271a 100644 --- a/src/Fable.Cli/Main.fs +++ b/src/Fable.Cli/Main.fs @@ -160,10 +160,27 @@ module private Util = |> FableTransforms.transformFile com |> Fable2Babel.Compiler.transformFile com - // TODO: Dummy interface until we have a dotnet port of SourceMapGenerator - // https://github.com/mozilla/source-map#with-sourcemapgenerator-low-level-api - let map = { new BabelPrinter.SourceMapGenerator with - member _.AddMapping(_,_,_,_,_) = () } + let mapPrinter, mapGen = + if cliArgs.SourceMaps then + let mapGenerator = SourceMapSharp.SourceMapGenerator() + + let print outPath = async { + let mapPath = outPath + ".map" + do! IO.File.AppendAllLinesAsync(outPath, [$"//# sourceMappingURL={IO.Path.GetFileName(mapPath)}"]) |> Async.AwaitTask + use sw = IO.File.OpenWrite(mapPath) + do! Text.Json.JsonSerializer.SerializeAsync(sw, mapGenerator.toJSON()) |> Async.AwaitTask + } + + print, { new BabelPrinter.SourceMapGenerator with + member _.AddMapping(orLine, orCol, genLine, genCol, name) = + let generated: SourceMapSharp.Util.MappingIndex = + {line = genLine; column = genCol} + let original: SourceMapSharp.Util.MappingIndex = + {line = orLine; column = orCol} + mapGenerator.AddMapping(generated, original, source=com.CurrentFile, ?name=name) } + else + Async.ignore, { new BabelPrinter.SourceMapGenerator with + member _.AddMapping(_,_,_,_,_) = () } let outPath = getOutJsPath cliArgs dedupTargetDir com.CurrentFile @@ -173,7 +190,8 @@ module private Util = // write output to file let writer = new FileWriter(com.CurrentFile, outPath, cliArgs, dedupTargetDir) - do! BabelPrinter.run writer map babel + do! BabelPrinter.run writer mapGen babel + do! mapPrinter outPath Log.always("Compiled " + File.getRelativePathFromCwd com.CurrentFile) diff --git a/src/Fable.Cli/RELEASE_NOTES.md b/src/Fable.Cli/RELEASE_NOTES.md index 9481d01832..edd5be0328 100644 --- a/src/Fable.Cli/RELEASE_NOTES.md +++ b/src/Fable.Cli/RELEASE_NOTES.md @@ -1,3 +1,8 @@ +### 3.1.0-beta-001 + +* Source map support @delneg +* Fix #2332: watch broken for certain directory structures @jwosty + ### 3.0.5 * Fixed compiler option parsing @ncave diff --git a/src/Fable.Cli/Util.fs b/src/Fable.Cli/Util.fs index b0ff6286fb..14d9600073 100644 --- a/src/Fable.Cli/Util.fs +++ b/src/Fable.Cli/Util.fs @@ -15,6 +15,7 @@ type CliArgs = FableLibraryPath: string option ForcePkgs: bool NoRestore: bool + SourceMaps: bool Exclude: string option Replace: Map RunProcess: RunProcess option @@ -211,6 +212,10 @@ module Async = disp.Dispose() onSuccess(v))) + let ignore (_: 'a) = async { + return () + } + module Imports = open Fable diff --git a/src/Fable.Transforms/Global/Compiler.fs b/src/Fable.Transforms/Global/Compiler.fs index 9ade9fb323..ced7b40538 100644 --- a/src/Fable.Transforms/Global/Compiler.fs +++ b/src/Fable.Transforms/Global/Compiler.fs @@ -1,7 +1,7 @@ namespace Fable module Literals = - let [] VERSION = "3.0.5" + let [] VERSION = "3.1.0-beta-001" type CompilerOptionsHelper = static member DefaultExtension = ".fs.js"