0

How is open and module prefixing supposed to work in rescript and rescript-react. It doesn't appear to be adhering to the documentation. For example, I have a file reader module

FileReader.res

module FileReader = {
  type fileReader
  type file = {"name": string, "lastModified": int, "size": int, "type__": string}

  @new external createFileReader: unit => fileReader = "FileReader"

  @bs.send
  external readAsDataURL: (fileReader, file) => unit = "readAsDataURL"

  let onload: (fileReader, string => unit) => unit = %raw(`
    function (reader, cb) {
      reader.onload = function (e) {
        cb(e.target.result);
      }
    }
  `)

  let fileToDataUrl: (file, string => unit) => unit = (file, continue) => {
    let reader = createFileReader()
    onload(reader, continue)
    readAsDataURL(reader, file)
  }
}

That I am trying to use from a react component:

Upload.res

open FileReader
let k = x => (_ => x)
let setState = stateHook => (newVal => stateHook(_ => newVal))
let firstFileFromEvent = event => ReactEvent.Form.target(event)["files"][0]

@react.component
let make = () => {
    let (dataUrl, setDataUrl) = React.useState(k(""))
    let setDataUrlState = setState(setDataUrl)

    let fileOnChange = (event) =>
        event ->
            firstFileFromEvent ->
            FileReader.fileToDataUrl(setDataUrlState)

    <div>
        <input type_="file" onChange=fileOnChange/>
        <img src=dataUrl/>
    </div>
}

The only way to get the code to compile is to

  1. open
  2. reference with the module name

my understanding is that you only need to do one or the other. If I remove the open statement, this is the output of the compiler

We've found a bug for you!
src/Upload.res:15:13-36

13 ┆ event -> 14 ┆ firstFileFromEvent -> 15 ┆
FileReader.fileToDataUrl(setDataUrlState) 16 ┆ 17 ┆

The value fileToDataUrl can't be found in FileReader

Adding the open statement back and changing the statement FileReader.fileToDataUrl(setDataUrlState) to fileToDataUrl(setDataUrlState) results in this exception:

We've found a bug for you!
src/Upload.res:15:13-25

13 ┆ event -> 14 ┆ firstFileFromEvent -> 15 ┆
fileToDataUrl(setDataUrlState) 16 ┆ 17 ┆

The value fileToDataUrl can't be found

The source i posted with both the open statement and the module prefix to the function call, compiles but has a warning:

Warning number 44
src/Upload.res:1:1-15

1 │ open FileReader 2 │ 3 │ let k = x => (_ => x)

this open statement shadows the module identifier FileReader (which is later used)

I am on a mac; using rescript 9.1.4;

akaphenom
  • 6,728
  • 10
  • 59
  • 109

1 Answers1

3

In rescript, every code file is itself a module. By putting your code into FileReader.res you've already created a module called FileReader. And by using module FileReader = { ... } you're creating another submodule called FileReader inside it.

The simple solution would then be to just not wrap it in a submodule. Alternatively, you could also open FileReader.FileReader.

What the warning is telling you is that when you open FileReader, you're importing another module called FileReader which shadows (i.e. hides) the top-level module that's also called FileReader.

glennsl
  • 28,186
  • 12
  • 57
  • 75