-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fable 5.0.0-alpha.4 JSX.jsx problem with not recognizing interpolated string #3999
Comments
Hello @halcwb, Can you please try to make a smaller reproduction code? |
Hope this is small enough: https://github.com/halcwb/Fable5Issue.git. I have gutted all code except just this part that seems to be the problem: module App
open Fable.Core
open Browser
open Fable.React
let inline private toReact (el: JSX.Element) : ReactElement = unbox el
[<JSX.Component>]
let View () =
let display showProgress (s: string) =
if showProgress then
JSX.jsx
$"""
import LinearProgress from '@mui/material/LinearProgress';
<LinearProgress>{s}</LinearProgress>
"""
else
JSX.jsx
$"""
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
{s}
</Typography>
</React.Fragment>
"""
let content = display true "Testing Fable 5"
JSX.jsx
$"""
import React from 'react';
<React.StrictMode>
<React.Fragment>
{content}
</React.Fragment>
</React.StrictMode>
"""
let app = ReactDomClient.createRoot (document.getElementById "app")
app.render (View() |> toReact) Hope this helps. |
@halcwb Looks related to dotnet/fsharp#16556 which converts some interpolated strings into string concatenation (for performance reasons), which then interferes with the Fable JSX. Before (Fable 4.24, F# 8.0): `
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
${s}
</Typography>
</React.Fragment>
` After (Fable 5.0.0-x, F# 9.0) concat("\n import LinearProgress from \'@mui/material/LinearProgress\';\n <LinearProgress>", s, ..."</LinearProgress>\n "); I'm not sure if this F# 9.0 behavior can be suppressed with some directive, but as a quick workaround adding a few dummy arguments helps avoid it, e.g.: JSX.jsx
$"""
{s}
""" use something like this: JSX.jsx
$"""{""}{""}
{s}
""" Not saying this is the best workaround ever, hopefully there is a better way to turn that feature off where needed ( |
@ncave Thanks for your quick reaction! Is there a way to inspect the output of the string interpolation as you show in your examples? |
I am not sure what you mean but that, but if you are speaking about the generated JavaScript, you can look at the generated files on the disk. |
Thanks. but the compiler crashes, there is no output other than this: import React from "react";
import * as client from "react-dom/client";
export function View() {
const display = (showProgress, s) => {
if (showProgress) {
return null;
}
else {
return null;
}
};
const content = display(true, "Testing Fable 5");
return <React.StrictMode>
<React.Fragment>
{content}
</React.Fragment>
</React.StrictMode>
;
}
export const app = client.createRoot(document.getElementById("app"));
app.render(<View></View>);
//# sourceMappingURL=App.jsx.map So you just have a `null`` instead of the original jsx string |
Ah sorry, didn't know about that. Then, I think the only way to explore the output/generation is by debugging Fable itself via this repository. This can be done by running From what I understand from @ncave, we probably would like to be able to make this check return Or perhaps, we can look at the generated code of |
Yes, if you make a function that returns just the interpolated string (without |
Your suggestion kind of works, but still results in incorrect javascript (see // doses not work
let display1 showProgress (text: string) =
if showProgress then
JSX.jsx
$"""{""}{""}
import LinearProgress from '@mui/material/LinearProgress';
<LinearProgress>{text}</LinearProgress>
"""
else
JSX.jsx
$"""{""}{""}
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
{text}
</Typography>
</React.Fragment>
"""
// shows corectly
let display2 showProgress (text: string) =
if showProgress then
printfn
$"""
import LinearProgress from '@mui/material/LinearProgress';
<LinearProgress>{text}</LinearProgress>
"""
else
printfn
$"""
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
{text}
</Typography>
</React.Fragment>
"""
// works
let display3 showProgress (text: obj) =
if showProgress then
JSX.jsx
$"""
import LinearProgress from '@mui/material/LinearProgress';
<LinearProgress>{text}</LinearProgress>
"""
else
JSX.jsx
$"""
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
{text}
</Typography>
</React.Fragment>
"""
// works
let display4 showProgress (text: string) =
if showProgress then
JSX.jsx
$"""
import LinearProgress from '@mui/material/LinearProgress';
<React.Fragment>
<LinearProgress>{text :> obj}</LinearProgress>
</React.Fragment>
"""
else
JSX.jsx
$"""
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
{text :> obj}
</Typography>
</React.Fragment>
""" Transpiles to const display1 = (showProgress, text) => {
if (showProgress) {
return {""}{""}
import LinearProgress from '@mui/material/LinearProgress';
<LinearProgress>{text}</LinearProgress>
;
}
else {
return {""}{""}
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
{text}
</Typography>
</React.Fragment>
;
}
};
const display2 = (showProgress_1, text_1) => {
if (showProgress_1) {
toConsole(`
import LinearProgress from '@mui/material/LinearProgress';
<LinearProgress>${text_1}</LinearProgress>
`);
}
else {
toConsole(`
import Typography from '@mui/material/Typography';
<React.Fragment>
<Typography variant="h6" gutterBottom >
${text_1}
</Typography>
</React.Fragment>
`);
}
};
const display3 = (showProgress_2, text_2) => {
if (showProgress_2) {
return <LinearProgress>{text_2}</LinearProgress>
;
}
else {
return <React.Fragment>
<Typography variant="h6" gutterBottom >
{text_2}
</Typography>
</React.Fragment>
;
}
};
const display4 = (showProgress_3, text_3) => {
if (showProgress_3) {
return <React.Fragment>
<LinearProgress>{text_3}</LinearProgress>
</React.Fragment>
;
}
else {
return <React.Fragment>
<Typography variant="h6" gutterBottom >
{text_3}
</Typography>
</React.Fragment>
;
}
};
const content = display3(true, "Testing Fable 5");
return <React.StrictMode>
<React.Fragment>
{content}
</React.Fragment>
</React.StrictMode>
; This is because the So, by just casting the interpolation arguments to objects you can avoid this issue. |
Does this issue still needs the label "needs reproduction"? |
Description
The code from in this repository: 9dee1b64a0f98b41e42242dfa4fa5e60d4961f5a
works with the fable 4 releases but not with the latest 5.0.0-alpha.4 release
Repro code
Expected and actual results
The JSX.jsx templates to be recognized as interpolated strings
Related information
.NET SDK:
Version: 9.0.101
Commit: eedb237549
Workload version: 9.0.100-manifests.3068a692
MSBuild version: 17.12.12+1cce77968
Runtime Environment:
OS Name: Mac OS X
OS Version: 12.7
OS Platform: Darwin
RID: osx-x64
Base Path: /usr/local/share/dotnet/sdk/9.0.101/
.NET workloads installed:
There are no installed workloads to display.
Configured to use loose manifests when installing new manifests.
Host:
Version: 9.0.0
Architecture: x64
Commit: 9d5a6a9aa4
.NET SDKs installed:
6.0.302 [/usr/local/share/dotnet/sdk]
6.0.403 [/usr/local/share/dotnet/sdk]
7.0.100 [/usr/local/share/dotnet/sdk]
8.0.100 [/usr/local/share/dotnet/sdk]
9.0.100 [/usr/local/share/dotnet/sdk]
9.0.101 [/usr/local/share/dotnet/sdk]
The text was updated successfully, but these errors were encountered: