Relay: [Modern] relay-compiler does not support complex folder-structures

Created on 21 Apr 2017  路  7Comments  路  Source: facebook/relay

relay-compiler assumes a single directory components/ where modulename == filename.
This enforces a de-facto layout standard for all Relay Modern projects, which may or may not suit developers.

what relay-compiler assumes:
./src/components
    Admin.js
    AdminChildComponent.js
example complex src folder:
./src
    /components
        /Admin
            index.js
            styles.css

            /ChildComponent
                index.js
                styles.css
example case & error for complex folders:
someuser ~/D/g/some-project> relay-compiler --src ./src --schema ./schema.graphql

Error: FindGraphQLTags: Container fragment names must be `<ModuleName>_<propName>`.
Got `users`, expected `index_users`.

Most helpful comment

From the documentation of FragmentContainer

A naming convention of _ for fragments is advised. This restriction is required while migrating from classic to modern APIs to allow for cross-compatibility.

I thought the naming format would be optional once we moved to Modern.

All 7 comments

This is not a folder complexity issue, but rather an issue with how you're naming your props on your component versus the fragment name. While there may be an issue with nested directories, it wouldn't manifest as this error.

If you have a container:

createFragmentContainer(MyContainer, {
  MyContainer_index_users: graphql`fragment MyContainer_users on Users { ... }`
})

it will throw. This is for a few reasons: in Compat mode, the fragment name is how we automatically create the prop key, and if you decide not to use an inner keyed object in your createFragmentContainer call, it's how we determine what the property name is. (Note, I can't fully remember the error, so it's possible I reversed which piece is in the fragment vs. the props).

While on the subject, how are nested modules and components (where it may or may not be index.js) supposed to work?

@mjmahone the exception is pertinent to the issue because it illustrates how Relay assumes module-names by filename (index.js -> index_fragment).

Another symptom of the problem is how your project directories will be cluttered by __generated__ folders unless you use a single components/ or containers/ folder

The wording of the error is a bit confusing, we should address that. The compiler requires that fragments be named <FIleNameMinusExtension>_<propName> (internally we follow a convention of naming files the same as the module name, hence the wording of the error message).

I can see how this naming scheme could cause issues for applications that are using commonjs and particularly having lots of files named index.js, we'll have to consider how to handle this.

cc @kassens @leebyron @mjmahone

From the documentation of FragmentContainer

A naming convention of _ for fragments is advised. This restriction is required while migrating from classic to modern APIs to allow for cross-compatibility.

I thought the naming format would be optional once we moved to Modern.

Looking at the source...
https://github.com/facebook/relay/blob/ca15340cb4ece8063ec393eb3d37c7792ad6d9d5/packages/relay-compiler/relay/codegen/FindGraphQLTags.js#L274
...you can pass a graphql fragment directly (without an object):

// App.js

export default createFragmentContainer(props => <Foo {...props} />,
  graphql`
    fragment App on User {
      ...Foo
    }
  `
)

This requires the use of the data prop: https://facebook.github.io/relay/docs/fragment-container.html#calling-component-instance-methods

A fix was added for "index" files for this issue, otherwise take a look at #2093

Was this page helpful?
0 / 5 - 0 ratings

Related issues

derekdowling picture derekdowling  路  3Comments

leebyron picture leebyron  路  3Comments

piotrblasiak picture piotrblasiak  路  3Comments

scotmatson picture scotmatson  路  3Comments

MartinDawson picture MartinDawson  路  3Comments