relay icon indicating copy to clipboard operation
relay copied to clipboard

Support custom module-name generator in relay-compiler

Open martinandert opened this issue 6 years ago • 17 comments

I know this has been shot down in #2101 already, but not being able to provide our own module-name generator is a major obstacle for us to truly adopting Relay in our codebase. Here's why:

We have several hundred components, and their file names aren't unique, since we don't use Haste for module resolution, but rather namespace our modules by putting their files in (sub)directories. For example, given the following file paths for three different List components,

src/desktop/account/orders/list.tsx
src/mobile/account/orders/list/index.tsx
src/some/other/list.tsx

the compiler's built-in getModuleName function turns all these file paths into the same module name, "list". Needless to say, the compiler will complain about module names not being unique.

Of course, we could give our components unique names, e.g.

src/desktop/account/orders/list/DesktopAccountOrdersList.tsx
src/mobile/account/orders/list/MobileAccountOrdersList.tsx
src/some/other/list/SomeOtherList.tsx

in order to get the desired module names, but seeing a naming scheme like this hurts my eyes and feels like a very ugly hack just to please the compiler. And no, ditching the namespacing-via-directories approach isn't really an option for us.

Also, relaxing the constraint of unique file names (see #2093) doesn't really help, since I consider it a feature that the compiler bails out when it detects this. It also helps when logging the operation name in fetchRelay. And having all Relay artifacts in one folder is also nice.

Besides that, I think it's a problem that getModuleName isn't exposed publicly, because then tools like eslint-plugin-relay have to copy its implementation to their codebases, which has the potential to break if the original implemention is changed.

To overcome these issues, we currently have a scripts.postinstall hook in our package.json which replaces the implementations of the getModuleName function in "node_modules/relay-compiler/bin/relay-compiler" as well as "node_modules/eslint-plugin-relay/src/utils.js" with our own implementation, which turns the file paths from the first example above into unique module names such as

DesktopAccountOrdersList
MobileAccountOrdersList
SomeOtherList

respectively.

It would be nice if we wouldn't have to resort to an ugly hack like this just to outfox the compiler.

The aforementioned issues are addressed by this pull request, in that it

  • introduces a new generateModuleNameFunction config option which allows users to pass their own module-name generator function, either as an actual function or as a path string which points to a local module that default-exports such a function (matching the behavior of the existing persistFunction config setting), and
  • exposes a public getGenerateModuleNameFunction(relayConfig) export which tools like eslint-plugin-relay can utilize instead of having to copy-and-paste code from the Relay codebase.

Please let me know your thoughts.

Thanks for such a great library!

martinandert avatar Nov 30 '19 19:11 martinandert

It's been a week since I opened the PR. Please let me know if you need anything else from me.

martinandert avatar Dec 09 '19 15:12 martinandert

I'm by no means am an anybody - but I think this would be an amazing addition. 👏

I am in a similar boat that you, but we got around that by firstly satisfying Relay, and then we put anything after the first bit, to then make it unique.

ie:

// src/desktop/account/orders/list.tsx
ListDesktopAccountOrders_Query
// src/mobile/account/orders/list/index.tsx
ListMobileAccountOrders_Query
// src/some/other/list.tsx
ListOther_Query

as long as the derived module name is in the start, and ends with what it wants you to, you're good.

Simply; List%something else%, has worked quite well for us. And relay throws a woobly when the names to conflict.

But yeah in saying that, it would be amazing to have consistency in those names too - so you don't start going ListUniqueA, ListUniqueB, etc... than actually making them be sensible.

maraisr avatar Dec 10 '19 03:12 maraisr

@maraisr Sadly this approach doesn't work for fragments. It has to be the exact name.

Parse error: Error: RelayFindGraphQLTags: Container fragment names must be 
`<ModuleName>_<propName>`. Got `ListCustomer_list`, expected `List_list`. in
"components/Customer/List.js"

pgeimer avatar Dec 26 '19 13:12 pgeimer

hey @martinandert , just stumble on this issue, i've got a bunch of indexes.js that i want to add with an @inline .... but i'm stuck with the Error: RelayFindGraphQLTags: Fragment names in graphql tags must be prefixed with the module name.

any way you could resolve conflicts/address the comments? so it has a chance to move forward?

eMerzh avatar May 09 '20 21:05 eMerzh

[...] any way you could resolve conflicts/address the comments?

@eMerzh I've rebased the PR against master in order to resolve the conflicts.

Which comments do you think need to be addressed?

martinandert avatar May 22 '20 11:05 martinandert

@martinandert nothing specific :)

thanks for the rebase 👍

eMerzh avatar May 22 '20 11:05 eMerzh

👀

jufemaiz avatar Jul 08 '20 06:07 jufemaiz

Now that ~10 months have passed (and efforts are made to port the compiler to Rust), I'm wondering whether this was even considered / looked at by the maintainers. It would be great to get some feedback on it.

/cc @kassens

martinandert avatar Sep 11 '20 06:09 martinandert

Our apologies for not following up on this sooner. As you can imagine we have limited resources, and we prioritize looking at critical bug fixes or improvements where we (core team) and the contributor have aligned on the change and the approach in advance.

This is something we can consider for the new Rust-based compiler. cc @tyao1 and @kassens

josephsavona avatar Sep 11 '20 15:09 josephsavona

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Dec 25 '20 13:12 stale[bot]

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

Adding a comment to prevent the PR from being autoclosed by the bot.

martinandert avatar Jan 04 '21 09:01 martinandert

any chance ?

hehex9 avatar Jan 13 '21 09:01 hehex9

Are there any updates on this?

charklewis avatar Apr 16 '21 10:04 charklewis

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Jan 08 '22 23:01 stale[bot]

Ummm … team? Any movement or review?

jufemaiz avatar May 20 '22 03:05 jufemaiz

@martinandert Are you willing to update this?

in order to get the desired module names, but seeing a naming scheme like this hurts my eyes and feels like a very ugly hack just to please the compiler. And no, ditching the namespacing-via-directories approach isn't really an option for us.

I'm in the same boat. I just bumped into this and further surprised namespacing via directories isn't just default behavior (assuming there's no naming collision)

tony avatar May 20 '22 17:05 tony

This would be super helpful, still. Any updates on this for either this compiler or the "new" Rust implementation?

zygopleural avatar Apr 24 '24 15:04 zygopleural