Reading a file contents

I wonder if I missed something.

I was a bit bummed that I had to write all that to read the contents of a file (and figure out how as I could not find an example in the docs!):

type blob
@send external text: blob => string = "text"
@module("fs") external openFile: string => promise<blob> = "openAsBlob"

let load = async name => {
  let v = await openFile(name)
  v->text
}

I also feel like I am cheating a bit as the “text” function actually returns a promise, but thanks to Javascript promise flattening my “load” function works fine.

Is it really that hard to read a file in ReScript? Are there any plans for a standard “Fs” module?

Much like Typescript, ReScript doesn’t necessarily target node; because of this, the docs try to be agnostic as to the runtime. Instead, the bindings to node are provided as a library, available here.

The bindings library doesn’t have much documentation, but through a combination of seeing the modules that live under the top-level NodeJs module, and reading the JS node docs, we can find readFileSync, which seems to be what you’re looking for.

Since you want the string representation, the simplest way implement load with this helper would be:

let load = NodeJs.Fs.readFileSyncWith(_, {encoding: "utf8"})

or, if you prefer a more explicit representation:

let load = name => NodeJs.Fs.readFileSyncWith(name, {encoding: "utf8"})

(We use NodeJs.Fs.readFileSyncWith rather than NodeJs.Fs.readFileSync because the former allows us to provide the second options argument)

3 Likes

That’s great, thank you. I did not think of looking for NodeJs bindings. The website only mentions React bindings.

Yeah, I’d imagine that’s because the React bindings are maintained by the ReScript team, whereas the NodeJs bindings are a third party library.