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.
./src/components
Admin.js
AdminChildComponent.js
./src
/components
/Admin
index.js
styles.css
/ChildComponent
index.js
styles.css
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`.
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
Most helpful comment
From the documentation of FragmentContainer
I thought the naming format would be optional once we moved to Modern.