facebook / relay

Relay is a JavaScript framework for building data-driven React applications.
https://relay.dev
MIT License
18.41k stars 1.83k forks source link

[relay 13] Rust Compiler does not generate enum files #3681

Open bigfootjon opened 2 years ago

bigfootjon commented 2 years ago

I was trying out these (undocumented) options in the new compiler:

https://github.com/facebook/relay/blob/main/compiler/crates/relay-typegen/src/config.rs#L37-L51

They don't appear to work correctly. When enabled, they transform enums from being defined inline (which DOES work correctly) to being an import type ... line to a module that doesn't exist. It looks like the codegen for enum files may be missing

alunyov commented 2 years ago

@kassens I think you may have the most context on what exactly we need to add to OSS compiler to enable this.

MaartenStaa commented 2 years ago

I was looking at this when working on #3800, but ran into a problem. To generate files for each enum, each enum from the schema needs to be represented as an artifact. I implemented how the content of the artifact should be generated, but the artifact's path posed a problem. Currently, the path for each artifact is determined using the following function:

// compiler/crates/relay-compiler/src/build_project/artifact_locator.rs

/// This function will create a correct path for artifact based on the project configuration
pub fn create_path_for_artifact(
    project_config: &ProjectConfig,
    source_file: SourceLocationKey,
    artifact_file_name: String,
) -> PathBuf 
    // ...
}

The issue is, there is no "real" source_file for the enums in the schema (other than the schema itself, but the schema doesn't expose its source file either). Since the output folder in the project config is optional, the generated files would normally be written under a __generated__ folder next to the source file, which is not appropriate in this case. It also seems the implementation of SourceLocationKey::path() for the Generated variant (which I am currently using), does not expect to ever be used as an actual path:

// compiler/crates/common/src/location.rs

    pub fn path(self) -> &'static str {
        match self {
            // ...
            SourceLocationKey::Generated => "<generated>",
        }
    }

So, what should the approach be? Where should the enum files be written to, when no output path is configured? Should they perhaps only be generated as artifacts when an output dir is set? Additionally, create_path_for_artifact supports output sharding, which also seems unfit for this case.

@kassens or @alunyov, any ideas?

My WIP commit can be found here: https://github.com/MaartenStaa/relay/commit/3b3ede53987901088e55ab1d95076f5f7c433720

alunyov commented 2 years ago

I think @kassens or even @gkz have more context here. As far as I know, internally, we have a dedicated build step fro these enum files, that leaves outside of the Relay compiler.

MaartenStaa commented 2 years ago

Hmm. Yeah more context would be great. Another thought I had was to, with a minor refactor, just put all the enum files in the configured output folder, and skip the generation if no output folder is configured. However, not sure if we really want to create that dependency, it feels a bit awkward.