Naming conflicts between models and components

In my projects, I typically make a data module, for my Entities or end points. These are the ones that follow the type t convention along with utils for fetching data.

Using a blog just as an example, I’d probably have a Comment.res module:

type t = {
  author: string,
  content: string
}

let fetchById = (commentId) => // ...
let fetchForPost = (postId) => // ...

The conflict comes when getting to the UI, naturally I’d also want to create a Comment.res file for the react component. But the name clashes.

Does anybody else struggle with this? Do you have a convention you like to avoid it?

There are two conventional approaches I’ve seen in the wild and personally adopted

  1. Preface the file name with the directory name

    // Models__Comment.res
    type t = {
      author: string,
      content: string
    }
      
    let fetchById = (commentId) => // ...
    let fetchForPost = (postId) => // ...
    
    // Components__Comment.res
    @react.component
    let make = () => / /...
    
    

    Then export them in a single top-level file

    //Models.res
    module Comment = Models__Comment
    
    //Components.res
    module Comment = Components__Comment
    

    Then you can do stuff like
    Models.Comment.fetchById() or <Components.Comment/>

  2. You can utilize rewatch and monorepo.
    Rewatch let’s you split your code into different packages with their own rescript.json file, while still running a single compile step.

    // packages/models/rescript.json
    {
    ...
    "namespace": "Models"
    }
    
    // packages/components/rescript.json
    {
    ...
    "namespace": "Components"
    }
    

    Then you can have files with the same name, because they are in different namespaces

2 Likes