diff --git a/src/compiler/WebSharper.Compiler.CSharp/Compile.fs b/src/compiler/WebSharper.Compiler.CSharp/Compile.fs index 68fec97b..90b9f4a9 100644 --- a/src/compiler/WebSharper.Compiler.CSharp/Compile.fs +++ b/src/compiler/WebSharper.Compiler.CSharp/Compile.fs @@ -133,8 +133,18 @@ let Compile config (logger: LoggerBase) tryGetMetadata = | Some (Bundle | Website | Service) -> Some (config.RuntimeMetadata, metas) | _ -> None + let isSitelet = + match config.ProjectType with + | Some Html -> + true + | Some Website + | _ when Option.isSome config.OutputDir -> + true + | _ -> + false + let js, currentMeta, sources, res = - ModifyAssembly logger (Some comp) refMeta currentMeta config.SourceMap config.TypeScriptDeclaration config.TypeScriptOutput config.AnalyzeClosures runtimeMeta assem (config.ProjectType = None) config.PreBundle + ModifyAssembly logger (Some comp) refMeta currentMeta config.SourceMap config.TypeScriptDeclaration config.TypeScriptOutput config.AnalyzeClosures runtimeMeta assem (config.ProjectType = None) config.PreBundle isSitelet match config.ProjectType with | Some (Bundle | Website) -> diff --git a/src/compiler/WebSharper.Compiler.FSharp/Compile.fs b/src/compiler/WebSharper.Compiler.FSharp/Compile.fs index 759b2a9b..dcfde549 100644 --- a/src/compiler/WebSharper.Compiler.FSharp/Compile.fs +++ b/src/compiler/WebSharper.Compiler.FSharp/Compile.fs @@ -248,9 +248,18 @@ let Compile (config : WsConfig) (warnSettings: WarnSettings) (logger: LoggerBase let isLibrary = config.ProjectType = None - let js, currentMeta, sources, res = - ModifyAssembly logger (Some comp) (getRefMeta()) currentMeta config.SourceMap config.TypeScriptDeclaration config.TypeScriptOutput config.AnalyzeClosures runtimeMeta assem isLibrary config.PreBundle + let isSitelet = + match config.ProjectType with + | Some Html -> + true + | Some Website + | _ when Option.isSome config.OutputDir -> + true + | _ -> + false + let js, currentMeta, sources, res = + ModifyAssembly logger (Some comp) (getRefMeta()) currentMeta config.SourceMap config.TypeScriptDeclaration config.TypeScriptOutput config.AnalyzeClosures runtimeMeta assem isLibrary config.PreBundle isSitelet match config.ProjectType with | Some (Bundle | Website) -> let wsRefs = diff --git a/src/compiler/WebSharper.Compiler/FrontEnd.fs b/src/compiler/WebSharper.Compiler/FrontEnd.fs index f0610efd..2f2e02fe 100644 --- a/src/compiler/WebSharper.Compiler/FrontEnd.fs +++ b/src/compiler/WebSharper.Compiler/FrontEnd.fs @@ -115,7 +115,7 @@ let CreateBundleJSOutput (logger: LoggerBase) refMeta current entryPoint = Some ("", "") -let CreateResources (logger: LoggerBase) (comp: Compilation option) (refMeta: M.Info) (current: M.Info) sourceMap dts ts closures (runtimeMeta: option) (a: Mono.Cecil.AssemblyDefinition) isLibrary prebundle = +let CreateResources (logger: LoggerBase) (comp: Compilation option) (refMeta: M.Info) (current: M.Info) sourceMap dts ts closures (runtimeMeta: option) (a: Mono.Cecil.AssemblyDefinition) isLibrary prebundle isSitelet = let assemblyName = a.Name.Name let sourceMap = false // TODO what about source mapping with all the small files let currentPosFixed, sources = @@ -214,6 +214,15 @@ let CreateResources (logger: LoggerBase) (comp: Compilation option) (refMeta: M. bname, js, trAddrMap ) |> Array.ofSeq |> Some + elif isSitelet then + let rootJS, addrMap = JavaScriptPackager.packageEntryPointReexport meta + let program, _, trAddrMap = rootJS |> WebSharper.Compiler.JavaScriptWriter.transformProgramAndAddrMap O.JavaScript WebSharper.Core.JavaScript.Readable addrMap + let js, _, _ = WebSharper.Compiler.JavaScriptPackager.programToString WebSharper.Core.JavaScript.Readable WebSharper.Core.JavaScript.Writer.CodeWriter program false + let trAddrMap = Dict.union [ trAddrMap; dict [ AST.Address.Global(), assemblyName ] ] + logger.TimedStage (sprintf "Writing reexports root.js") + Some [| + "root", js, trAddrMap + |] else None let updated = @@ -382,16 +391,16 @@ let CreateResources (logger: LoggerBase) (comp: Compilation option) (refMeta: M. addMeta() None, currentPosFixed, sources, res.ToArray() -let ModifyCecilAssembly (logger: LoggerBase) (comp: Compilation option) (refMeta: M.Info) (current: M.Info) sourceMap dts ts closures runtimeMeta (a: Mono.Cecil.AssemblyDefinition) isLibrary prebundle = - let jsOpt, currentPosFixed, sources, res = CreateResources logger comp refMeta current sourceMap dts ts closures runtimeMeta a isLibrary prebundle +let ModifyCecilAssembly (logger: LoggerBase) (comp: Compilation option) (refMeta: M.Info) (current: M.Info) sourceMap dts ts closures runtimeMeta (a: Mono.Cecil.AssemblyDefinition) isLibrary prebundle isSitelet = + let jsOpt, currentPosFixed, sources, res = CreateResources logger comp refMeta current sourceMap dts ts closures runtimeMeta a isLibrary prebundle isSitelet let pub = Mono.Cecil.ManifestResourceAttributes.Public for name, contents in res do Mono.Cecil.EmbeddedResource(name, pub, contents) |> a.MainModule.Resources.Add jsOpt, currentPosFixed, sources, res -let ModifyAssembly (logger: LoggerBase) (comp: Compilation option) (refMeta: M.Info) (current: M.Info) sourceMap dts ts closures runtimeMeta (assembly : Assembly) isLibrary = - ModifyCecilAssembly logger comp refMeta current sourceMap dts ts closures runtimeMeta assembly.Raw isLibrary +let ModifyAssembly (logger: LoggerBase) (comp: Compilation option) (refMeta: M.Info) (current: M.Info) sourceMap dts ts closures runtimeMeta (assembly : Assembly) isLibrary prebundle isSitelet = + ModifyCecilAssembly logger comp refMeta current sourceMap dts ts closures runtimeMeta assembly.Raw isLibrary prebundle isSitelet let AddExtraAssemblyReferences (wsrefs: Assembly seq) (assembly : Assembly) = let a = assembly.Raw diff --git a/src/compiler/WebSharper.Compiler/JavaScriptPackager.fs b/src/compiler/WebSharper.Compiler/JavaScriptPackager.fs index 1192f4c8..2023bece 100644 --- a/src/compiler/WebSharper.Compiler/JavaScriptPackager.fs +++ b/src/compiler/WebSharper.Compiler/JavaScriptPackager.fs @@ -1378,16 +1378,82 @@ let programToString pref (getWriter: unit -> WebSharper.Core.JavaScript.Writer.C WebSharper.Core.JavaScript.Writer.WriteProgram pref writer program writer.GetCodeFile(), writer.GetMapFile(), isJSX -let packageEntryPoint (runtimeMeta: M.Info) (graph: DependencyGraph.Graph) asmName = +let packageEntryPointReexport (runtimeMeta: M.Info) = + + let allBundleContent = ResizeArray() + let addresses = ResizeArray() - //let webControls = - // runtimeMeta.Classes |> Seq.choose (fun (KeyValue(td, (_, _, cls))) -> - // match cls with - // | Some cls when isWebControl cls -> - // Some td - // | _ -> None - // ) - // |> Array.ofSeq + for qi in runtimeMeta.Quotations.Values do + allBundleContent.Add(qi.TypeDefinition, Some qi.Method) + + for KeyValue((td, m), _) in runtimeMeta.QuotedMethods do + allBundleContent.Add(td, Some m) + + for wc in runtimeMeta.WebControls do + allBundleContent.Add(wc.Key.TypeDefinition, None) + + for td, m in allBundleContent do + match runtimeMeta.Classes.TryFind td with + | Some (addr, _, Some cls) -> + match m with + | Some m -> + match cls.Methods.TryFind m with + | Some mi -> + match mi.CompiledForm with + | M.Static (name, _, _) -> addresses.Add(addr) + | M.Func (name, _) -> addresses.Add(addr.Func(name)) + | M.GlobalFunc (faddr, _) -> addresses.Add(faddr) + | _ -> () + | _ -> () + | _ -> + addresses.Add(addr) + | _ -> () + + let addressMap = Dictionary() + + addressMap.Add("Runtime", Address.RuntimeAddr [ "default" ]) + + for a in Seq.distinct addresses do + addressMap |> Resolve.getRenamedInDict a.Address.Head a |> ignore + + let revAddressMap = addressMap |> Dict.swap + + let finalAddrMap = Dictionary() + + let rootJs = + revAddressMap |> Seq.groupBy (fun kv -> kv.Key.Module) + |> Seq.map (fun (m, addrs) -> + let namedImports = ResizeArray() + for KeyValue(a, n) in addrs do + match a.Address |> List.rev |> List.head with + | "default" -> + let newName = + match m with + | JavaScriptModule m -> + m.Name.Replace('.', '_').Replace('`', '_') + | DotNetType m -> + (m.Name.Split([| '/'; '.' |]) |> Array.last).Split('`') |> Array.head + | _ -> "x" + let x = Id.New newName + namedImports.Add("default", x) + finalAddrMap.Add(a, x) + | i -> + let x = Id.New n + namedImports.Add(i, x) + finalAddrMap.Add(a, x) + let moduleName = + match m with + | JavaScriptModule m + | DotNetType m -> + "../" + m.Assembly + "/" + m.Name + ".js" + | _ -> "" + ExportDecl (false, Import(None, None, List.ofSeq namedImports, moduleName)) + ) + |> List.ofSeq + + rootJs, finalAddrMap + +let packageEntryPoint (runtimeMeta: M.Info) (graph: DependencyGraph.Graph) asmName = let all = ResizeArray() let bundles = Dictionary() diff --git a/src/compiler/WebSharper.Compiler/JavaScriptWriter.fs b/src/compiler/WebSharper.Compiler/JavaScriptWriter.fs index 410e01c8..2d89922d 100644 --- a/src/compiler/WebSharper.Compiler/JavaScriptWriter.fs +++ b/src/compiler/WebSharper.Compiler/JavaScriptWriter.fs @@ -151,6 +151,13 @@ type CollectVariables(env: Environment) = override this.VisitAlias(a, _, _) = defineId env a |> ignore + override this.VisitExportDecl(_, s) = + match s with + | Import(None, None, namedImports, _) -> + namedImports |> List.iter (snd >> defineId env >> ignore) + | _ -> + this.VisitStatement(s) + override this.VisitImport(d, f, n, m) = if m = "" then // global values used @@ -549,6 +556,14 @@ and transformStatement (env: Environment) (statement: Statement) : J.Statement = b |> Option.map (defineId env), c |> List.map (fun (n, x) -> n, defineId env x), d) + | ExportDecl (a, Import(None, None, b, c)) -> + J.Export (a, + J.Import( + None, + None, + b |> List.map (fun (n, x) -> n, transformId env x), + c) + ) | ExportDecl (a, b) -> J.Export (a, trS b) | Declare a -> @@ -745,5 +760,6 @@ let transformProgramAndAddrMap output pref (addrMap: IDictionary) s let env = Environment.New(pref, output) let cvars = CollectVariables(env) statements |> List.iter cvars.VisitStatement - let trAddrMap = addrMap |> Dict.map (fun id -> (transformId env id).Name) - (statements |> List.map (transformStatement env) |> flattenJS), env.IsJSX.Value, trAddrMap + (statements |> List.map (transformStatement env) |> flattenJS), + env.IsJSX.Value, + (addrMap |> Dict.map (fun id -> (transformId env id).Name)) diff --git a/src/sitelets/WebSharper.Sitelets/Content.fs b/src/sitelets/WebSharper.Sitelets/Content.fs index cb23d8a6..853f1e40 100644 --- a/src/sitelets/WebSharper.Sitelets/Content.fs +++ b/src/sitelets/WebSharper.Sitelets/Content.fs @@ -137,8 +137,13 @@ module Content = |> Seq.collect importsOf |> Array.ofSeq + let hasRoot = + ctx.Metadata.PreBundle.Count = 1 && ctx.Metadata.PreBundle.ContainsKey("root") + let bundleName = - if ctx.Metadata.PreBundle.Count > 0 && allImports.Length > 0 then + if hasRoot then + Some "root" + elif ctx.Metadata.PreBundle.Count > 0 && allImports.Length > 0 then match requiredBundles with | [||] -> if ctx.Metadata.PreBundle.ContainsKey("all") then Some "all" else None @@ -197,7 +202,32 @@ module Content = | None -> None | Some bundle -> match bundle.TryFind a with - | Some b -> Some ("wsbundle." + b) + | Some b -> + if hasRoot then + match imported.TryGetValue(f) with + | true, i -> + Some i + | _ -> + let i = "i" + string (imported.Count + 1) + match f.Address |> List.rev with + | [] -> failwith "empty address" + | a :: r -> + let j = + match a with + | "default" -> + match r with + | [] -> + i :: r |> String.concat "." + | _ :: rr -> + i :: rr |> String.concat "." + | _ -> + i :: r |> String.concat "." + imported.Add(f, j) + let asmName = bundle[AST.Address.Global()] + scriptsTw.WriteLine($"""import {{ {b} as {i} }} from "{url}{asmName}/root.js";""") + Some j + else + Some ("wsbundle." + b) | None -> match a.Address with | h :: t -> @@ -272,7 +302,7 @@ module Content = scriptsTw.WriteLine($"""{v}.$postinit("{i}");""") | _ -> () - Some activate, bundleName |> Option.map Array.singleton + Some activate, if hasRoot then None else bundleName |> Option.map Array.singleton else None, None diff --git a/tests/Web.FSharp/Main.html b/tests/Web.FSharp/Main.html index b0053a97..700151b3 100644 --- a/tests/Web.FSharp/Main.html +++ b/tests/Web.FSharp/Main.html @@ -30,6 +30,7 @@ margin: 20px 0; } + diff --git a/tests/Web.FSharp/Startup.fs b/tests/Web.FSharp/Startup.fs index 317575c1..7f47fbe3 100644 --- a/tests/Web.FSharp/Startup.fs +++ b/tests/Web.FSharp/Startup.fs @@ -24,6 +24,14 @@ type Startup () = app.UseDeveloperExceptionPage() |> ignore app.UseAuthentication() + .Use(fun context (next: RequestDelegate) -> + if context.Request.Path.StartsWithSegments("/Scripts") || context.Request.Path.StartsWithSegments("/@vite") then + let proxyRequest = context.Request.Path.Value + context.Response.Redirect($"http://localhost:5173{proxyRequest}") + Task.CompletedTask + else + next.Invoke(context) + ) .UseStaticFiles() .UseWebSharper() .Run(fun context -> diff --git a/tests/Web.FSharp/Web.FSharp.fsproj b/tests/Web.FSharp/Web.FSharp.fsproj index ec5c4953..cae08571 100644 --- a/tests/Web.FSharp/Web.FSharp.fsproj +++ b/tests/Web.FSharp/Web.FSharp.fsproj @@ -8,6 +8,7 @@ False + @@ -37,6 +38,9 @@ + + + \ No newline at end of file diff --git a/tests/Web.FSharp/package-lock.json b/tests/Web.FSharp/package-lock.json new file mode 100644 index 00000000..2bbe6286 --- /dev/null +++ b/tests/Web.FSharp/package-lock.json @@ -0,0 +1,426 @@ +{ + "name": "Web.FSharp", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "is-sorted": "^1.0.5" + }, + "devDependencies": { + "esbuild": "^0.19.9" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", + "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", + "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", + "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", + "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", + "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", + "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", + "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", + "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", + "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", + "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", + "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", + "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", + "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", + "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", + "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", + "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", + "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", + "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", + "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", + "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", + "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", + "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", + "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", + "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.10", + "@esbuild/android-arm": "0.19.10", + "@esbuild/android-arm64": "0.19.10", + "@esbuild/android-x64": "0.19.10", + "@esbuild/darwin-arm64": "0.19.10", + "@esbuild/darwin-x64": "0.19.10", + "@esbuild/freebsd-arm64": "0.19.10", + "@esbuild/freebsd-x64": "0.19.10", + "@esbuild/linux-arm": "0.19.10", + "@esbuild/linux-arm64": "0.19.10", + "@esbuild/linux-ia32": "0.19.10", + "@esbuild/linux-loong64": "0.19.10", + "@esbuild/linux-mips64el": "0.19.10", + "@esbuild/linux-ppc64": "0.19.10", + "@esbuild/linux-riscv64": "0.19.10", + "@esbuild/linux-s390x": "0.19.10", + "@esbuild/linux-x64": "0.19.10", + "@esbuild/netbsd-x64": "0.19.10", + "@esbuild/openbsd-x64": "0.19.10", + "@esbuild/sunos-x64": "0.19.10", + "@esbuild/win32-arm64": "0.19.10", + "@esbuild/win32-ia32": "0.19.10", + "@esbuild/win32-x64": "0.19.10" + } + }, + "node_modules/is-sorted": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-sorted/-/is-sorted-1.0.5.tgz", + "integrity": "sha512-KZJvKDrI+Kg3ixeDaZQIt7RIwcGnm07+NSipyj1r9MtjDrLG678ETy4yO6dBJLUjejPdge9fLCGxsWkQO/3PJg==" + } + } +} diff --git a/tests/Web.FSharp/package.json b/tests/Web.FSharp/package.json new file mode 100644 index 00000000..35c01ad3 --- /dev/null +++ b/tests/Web.FSharp/package.json @@ -0,0 +1,8 @@ +{ + "devDependencies": { + "esbuild": "^0.19.9" + }, + "dependencies": { + "is-sorted": "^1.0.5" + } +} diff --git a/tests/Web.FSharp/vite.config.js b/tests/Web.FSharp/vite.config.js new file mode 100644 index 00000000..ce57031c --- /dev/null +++ b/tests/Web.FSharp/vite.config.js @@ -0,0 +1,10 @@ +module.exports = { + root: "wwwroot", + build: { + rollupOptions: { + input: [ + "./Scripts/WebSharper/Web.FSharp/all.js" + ] + } + } +} \ No newline at end of file diff --git a/tests/Web.FSharp/wsconfig.json b/tests/Web.FSharp/wsconfig.json index dadd0c66..7c8c1f21 100644 --- a/tests/Web.FSharp/wsconfig.json +++ b/tests/Web.FSharp/wsconfig.json @@ -2,5 +2,6 @@ "$schema": "https://websharper.com/wsconfig.schema.json", "project": "web", "outputDir": "wwwroot", - "downloadResources": true + "downloadResources": true, + "runtimeMetadata": "full" } diff --git a/tests/Web/Web.csproj b/tests/Web/Web.csproj index d8361af2..cd45c892 100644 --- a/tests/Web/Web.csproj +++ b/tests/Web/Web.csproj @@ -35,10 +35,8 @@ - + - - diff --git a/tests/Web/package-lock.json b/tests/Web/package-lock.json index 2790927e..068ea3a4 100644 --- a/tests/Web/package-lock.json +++ b/tests/Web/package-lock.json @@ -4,6 +4,9 @@ "requires": true, "packages": { "": { + "dependencies": { + "is-sorted": "^1.0.5" + }, "devDependencies": { "esbuild": "^0.19.9" } @@ -413,6 +416,11 @@ "@esbuild/win32-ia32": "0.19.10", "@esbuild/win32-x64": "0.19.10" } + }, + "node_modules/is-sorted": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-sorted/-/is-sorted-1.0.5.tgz", + "integrity": "sha512-KZJvKDrI+Kg3ixeDaZQIt7RIwcGnm07+NSipyj1r9MtjDrLG678ETy4yO6dBJLUjejPdge9fLCGxsWkQO/3PJg==" } } } diff --git a/tests/Web/package.json b/tests/Web/package.json index 7148ec47..7e9a9d66 100644 --- a/tests/Web/package.json +++ b/tests/Web/package.json @@ -4,5 +4,8 @@ }, "devDependencies": { "esbuild": "^0.19.9" + }, + "dependencies": { + "is-sorted": "^1.0.5" } } diff --git a/tests/Web/wsconfig.json b/tests/Web/wsconfig.json index 937a8a9a..51b81715 100644 --- a/tests/Web/wsconfig.json +++ b/tests/Web/wsconfig.json @@ -4,8 +4,5 @@ "outputDir": "wwwroot", "downloadResources": true, "runtimeMetadata": "full", - "preBundle": true, - "release": { - "preBundle": true - } + "preBundle": true } diff --git a/tests/WebSharper.Module.Tests/Import.fs b/tests/WebSharper.Module.Tests/Import.fs index 0232566a..df3198fc 100644 --- a/tests/WebSharper.Module.Tests/Import.fs +++ b/tests/WebSharper.Module.Tests/Import.fs @@ -47,6 +47,9 @@ type MyClassInline [] () = [] let sayHiFunc (str: string) = X +[] +let isSorted (array: 'T[]) = X + [] module JSXTest = let html() = @@ -126,4 +129,9 @@ let Tests = let c = WebSharper.InterfaceGenerator.Tests.WIGtest4() equal (c.SayHiInst "World") "Hello, World!" } + + Test "npm import" { + isTrue (isSorted([| 1; 2; 3 |])) + isFalse (isSorted([| 1; 3; 2 |])) + } }