Use ReScript with Svelte

Hi, Is there a way to use ReScript inside svelte?

example with typescript:

<script lang="ts">
   let count: number  = 0;
</script>
<span>
  {name}
</span>

it will be great if we can use ReScript as well:

<script lang="res">
   let count: int  = 0;
</script>
<span>
  {name}
</span>
2 Likes

The easiest option may be to write all your logic inside Rescript modules and import them for use inside a svelte component.

4 Likes

found this svelte-with-rescript.

1 Like

How is it going using svelte plus Rescript?

If anyone who knows Svelte is interested in pursuing this it’d be fun to throw some ideas around. <script lang="res"> would be cool!

2 Likes

So Svelte has docs on their preprocessor, which easily lets you access and replace content within the <script> tag. So in your .svelte file, you can do:

<script lang="res">
    Console.log("Hello World");
</script>

And in the build plugin you can access the code block easily during their build step:

  preprocess: {
    script: ({ content, attributes }) => {
      if (attributes.lang !== "res") return;

      console.log("This file is a res file", content);
    },
  },
transforming (1) src/main.js This file is a res file 

    Console.log("Hello World");

The question though is what approach you can take on the rescript side?

  1. Can you build a res file in memory with a reference to the current proejct dir, and just return the contents?
  2. Would you need a custom pre-preprocess step that finds these code blocks, creates hidden .custom/Svelte_App.res files, does rescript build and then during svelte just returns .custom/Svelte_App.res.js
2 Likes

You might make this work by using a temporary file.
Using latest v12 alpha you can get the compiler arguments from rewatch

npx rewatch --rescript-version 12.0.0-alpha.13 --compiler-args /Users/nojaf/Projects/my-project/src/Context.res

{
  "compiler_args": [
    "-bs-ns",
    "Kaplay",
    "-I",
    "../ocaml",
    "-uncurried",
    "-bs-package-name",
    "@nojaf/project-name",
    "-bs-package-output",
    "esmodule:src:.res.mjs",
    "-bs-v",
    "12.0.0-alpha.13",
    "src/Context.ast"
  ],
  "parser_args": [
    "-bs-v",
    "12.0.0-alpha.13",
    "-uncurried",
    "-absname",
    "-bs-ast",
    "-o",
    "src/Context.ast",
    "../../src/Context.res"
  ]
}

Running npx bsc with the sets of arguments should create everything.
(Using your lib/bs as cwd)
And you can read your temp file from disk.

That being said, I’m not sure how you would enable tooling support.

With some compiler changes, it might be possible to get the final output in stdout instead of disk.
That would be interesting to have in general.

2 Likes

Yeah, what @nojaf suggests above would be a great way to test this put. Doing some minor research, it seems that .svelte files are only ever imported into other .svelte files for using as components, so while that part still needs working out (%raw should be fine for now), the approach outlined above should be very much doable. As in - in a Svelte preprocessor, take the JS content, write it to a temporary file, and then compile it using the compiler command Rewatch can give you for your current project.

There are a ton of rough edges here that we’d be happy to smoothen out if anyone is interested in using Svelte with ReScript, and gets going trying these things out. This includes editor tooling as well (which we also can figure out how to support if there’s proper interest).

1 Like

There’s also the possibility of also writing the ReScript found in Svelte script tags to actual files, kind of like you describe @hellos3b.

Lots of possibilities. We can figure out a nice approach for all of this if there’s genuine interest (and action) in getting experimenting with all of this.

2 Likes

I made a small PoC that implements support for <script lang="res"> in .svelte files. There’s plenty of things to fix, but this shows that it’s possible: GitHub - zth/rescript-svelte-example: PoC of supporting `lang="res"` in Svelte.

Happy to see someone pick this up and explore more of it.

2 Likes