Skip to content

Commit

Permalink
feat(relay): Add outputFileExtension option (#222)
Browse files Browse the repository at this point in the history
# Description

## Feature

In this PR we add `outputFileExtension` parameter in the config that can
be:
- `ts`
- `js`
- `undefined`

When it's undefined we do the same behaviour as now which is controlled
by `language` parameter
When it's configured we use the `outputFileExtension` parameter to
specify which extension to use in the transpiled path import

Example of usage: 
```typescript
 [
          '@swc/plugin-relay',
          {
            rootDir: __dirname,
            artifactDirectory: './src/relay/__generated__',
            eagerEsModules: true,
            outputFileExtension: 'js'
          },
],
```

## Initial issue

We are migrating from `babel` to `swc` and currently our babel plugin 

The output in dist are javascript esm and instead of having this

```javascript
import __stuffFragment1 from "../../../relay/__generated__/stuffFragment.graphql";
import { graphql } from "react-relay";
export const stuffFragment = __stuffFragment1;
```
we have this:
```javascript
import __stuffFragment1 from "../../../relay/__generated__/stuffFragment.graphql.ts";
import { graphql } from "react-relay";
export const stuffFragment = __stuffFragment1;
```
Basically it add `.ts` at the end but our files are javascript
transpiled files

- I know it's due to default fallback to ts language:
https://github.com/swc-project/plugins/blob/91fabf814285011eede6e80712da8ad7da1ae7ec/packages/relay/src/lib.rs#L42
- I know by default ts language add `.ts` at the end:
https://github.com/swc-project/plugins/blob/91fabf814285011eede6e80712da8ad7da1ae7ec/packages/relay/transform/src/lib.rs#L165

Is it a configuration issue on our side or a plugin issue that by
default transpilation import path should not have extensions ? If it's a
configuration issue sorry in advance I thought the inputs were the same
as the babel plugin

If we consider it as a bug I'll obviously fix this PR and update test,
otherwise I'll close it and change the config on my side


Swc config:
```javascript
const config = {
  jsc: {
    baseUrl: 'src',
    parser: {
      syntax: 'typescript',
      tsx: true,
    },
    target: 'esnext',
    paths: {
      '@xxx/*': ['*'],
    },
    experimental: {
      plugins: [
        [
          '@swc/plugin-relay',
          {
            rootDir: __dirname,
            artifactDirectory: './src/relay/__generated__',
            eagerEsModules: true,
          },
        ],
      ],
    },
  },
  test: '(.ts|.tsx|.js|.jsx)',
};
```

previous babel config for relay:
```javascript
  plugins: [
    [
      'relay',
      {
        artifactDirectory: './src/relay/__generated__',
      },
    ],
```

Note: We cannot put `javascript` language type as our input files are
`typescript`
  • Loading branch information
JulienKode authored Oct 25, 2023
1 parent 65cd6b5 commit dc992bb
Show file tree
Hide file tree
Showing 30 changed files with 176 additions and 40 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/constify/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-constify",
"version": "0.1.23",
"version": "0.1.24",
"description": "SWC plugin for optimization",
"main": "swc_plugin_constify.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/constify/transform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_constify"
repository = "https://github.com/swc-project/plugins.git"
version = "0.18.0"
version = "0.19.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/emotion/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-emotion",
"version": "2.5.93",
"version": "2.5.94",
"description": "SWC plugin for emotion css-in-js library",
"main": "swc_plugin_emotion.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/emotion/transform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_emotion"
repository = "https://github.com/swc-project/plugins.git"
version = "0.54.0"
version = "0.55.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
2 changes: 1 addition & 1 deletion packages/jest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-jest",
"version": "1.5.93",
"version": "1.5.94",
"description": "SWC plugin for jest",
"main": "swc_plugin_jest.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/loadable-components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-loadable-components",
"version": "0.3.93",
"version": "0.3.94",
"description": "SWC plugin for `@loadable/components`",
"main": "swc_plugin_loadable_components.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/noop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-noop",
"version": "1.5.91",
"version": "1.5.92",
"description": "Noop SWC plugin, for debugging",
"main": "swc_plugin_noop.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-remove-properties/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-react-remove-properties",
"version": "1.5.93",
"version": "1.5.94",
"description": "SWC plugin for https://www.npmjs.com/package/babel-plugin-react-remove-properties",
"main": "swc_plugin_react_remove_properties.wasm",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/react-remove-properties/transform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "react_remove_properties"
repository = "https://github.com/swc-project/plugins.git"
version = "0.6.0"
version = "0.7.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
21 changes: 21 additions & 0 deletions packages/relay/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,24 @@ const swcConfig = require("./.swcrc.js")
```

> Note: We're using a `.swcrc.js` file extension up above and importing the config directly because Relay needs access to `__dirname`, which can't be derived from the default JSON parsed from `.swcrc`.
#### Output import paths

By default, `@swc/plugin-relay` will transpile import paths based on the `language` option.
You can use `outputFileExtension` to change the file extension of the generated import paths.

```js
plugins: [
[
"@swc/plugin-relay",
{
rootDir: __dirname,
artifactDirectory: "src/__generated__",
language: "typescript",
eagerEsModules: true,
outputFileExtension: "js",
},
],
],
```
In this example typescript graphql files will output transpiled import path of `javascript` ending with `.js`.
2 changes: 1 addition & 1 deletion packages/relay/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-relay",
"version": "1.5.93",
"version": "1.5.94",
"description": "SWC plugin for relay",
"main": "swc_plugin_relay.wasm",
"types": "./types.d.ts",
Expand Down
6 changes: 5 additions & 1 deletion packages/relay/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use swc_core::{
ecma::{ast::Program, visit::FoldWith},
plugin::{plugin_transform, proxies::TransformPluginProgramMetadata},
};
use swc_relay::{relay, Config, RelayLanguageConfig};
use swc_relay::{relay, Config, RelayLanguageConfig, OutputFileExtension};

#[plugin_transform]
fn relay_plugin_transform(program: Program, metadata: TransformPluginProgramMetadata) -> Program {
Expand Down Expand Up @@ -40,6 +40,9 @@ fn relay_plugin_transform(program: Program, metadata: TransformPluginProgramMeta
let language = plugin_config["language"]
.as_str()
.map_or(RelayLanguageConfig::TypeScript, |v| v.try_into().unwrap());
let output_file_extension = plugin_config["outputFileExtension"]
.as_str()
.map_or(OutputFileExtension::Undefined, |v| v.try_into().unwrap());
let eager_es_modules = plugin_config["eagerEsModules"]
.as_bool()
.unwrap_or_default();
Expand All @@ -48,6 +51,7 @@ fn relay_plugin_transform(program: Program, metadata: TransformPluginProgramMeta
artifact_directory,
language,
eager_es_modules,
output_file_extension
};

let mut relay = relay(
Expand Down
2 changes: 1 addition & 1 deletion packages/relay/transform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "swc_relay"
repository = "https://github.com/swc-project/plugins.git"
version = "0.26.0"
version = "0.27.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
45 changes: 37 additions & 8 deletions packages/relay/transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ pub enum RelayLanguageConfig {
Flow,
}

#[derive(Copy, Clone, Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum OutputFileExtension {
TypeScript,
JavaScript,
Undefined
}

impl<'a> TryFrom<&'a str> for RelayLanguageConfig {
type Error = String;

Expand All @@ -33,12 +41,31 @@ impl<'a> TryFrom<&'a str> for RelayLanguageConfig {
}
}


impl<'a> TryFrom<&'a str> for OutputFileExtension {
type Error = String;

fn try_from(value: &'a str) -> Result<Self, Self::Error> {
match value {
"ts" => Ok(Self::TypeScript),
"js" => Ok(Self::JavaScript),
_ => Err(format!("Unexpected output file extension value '{}'", value)),
}
}
}

impl Default for RelayLanguageConfig {
fn default() -> Self {
Self::Flow
}
}

impl Default for OutputFileExtension {
fn default() -> Self {
Self::Undefined
}
}

#[derive(Debug, Clone)]
struct RelayImport {
path: JsWord,
Expand Down Expand Up @@ -81,6 +108,8 @@ pub struct Config {
pub language: RelayLanguageConfig,
#[serde(default)]
pub eager_es_modules: bool,
#[serde(default)]
pub output_file_extension: OutputFileExtension,
}

fn pull_first_operation_name_from_tpl(tpl: &TaggedTpl) -> Option<String> {
Expand Down Expand Up @@ -159,14 +188,14 @@ impl<'a> Relay<'a> {
real_file_name: &Path,
definition_name: &str,
) -> Result<PathBuf, BuildRequirePathError> {
let filename = match &self.config.language {
RelayLanguageConfig::Flow => format!("{}.graphql.js", definition_name),
RelayLanguageConfig::TypeScript => {
format!("{}.graphql.ts", definition_name)
}
RelayLanguageConfig::JavaScript => {
format!("{}.graphql.js", definition_name)
}
let filename = match &self.config.output_file_extension {
OutputFileExtension::JavaScript => format!("{}.graphql.js", definition_name),
OutputFileExtension::TypeScript => format!("{}.graphql.ts", definition_name),
OutputFileExtension::Undefined => match &self.config.language {
RelayLanguageConfig::Flow => format!("{}.graphql.js", definition_name),
RelayLanguageConfig::TypeScript => format!("{}.graphql.ts", definition_name),
RelayLanguageConfig::JavaScript => format!("{}.graphql.js", definition_name),
},
};

if let Some(artifact_directory) = &self.config.artifact_directory {
Expand Down
56 changes: 55 additions & 1 deletion packages/relay/transform/tests/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::PathBuf;

use swc_common::FileName;
use swc_ecma_transforms_testing::test_fixture;
use swc_relay::{relay, Config, RelayLanguageConfig};
use swc_relay::{relay, Config, RelayLanguageConfig, OutputFileExtension};

#[testing::fixture("tests/fixture/simple/**/input.js")]
fn fixture(input: PathBuf) {
Expand All @@ -16,6 +16,7 @@ fn fixture(input: PathBuf) {
artifact_directory: None,
language: RelayLanguageConfig::TypeScript,
eager_es_modules: false,
output_file_extension: OutputFileExtension::Undefined,
},
FileName::Real("file.js".parse().unwrap()),
Default::default(),
Expand All @@ -41,6 +42,59 @@ fn fixture_es_modules(input: PathBuf) {
artifact_directory: None,
language: RelayLanguageConfig::TypeScript,
eager_es_modules: true,
output_file_extension: OutputFileExtension::Undefined,
},
FileName::Real("file.js".parse().unwrap()),
Default::default(),
None,
None,
)
},
&input,
&output,
Default::default(),
);
}

#[testing::fixture("tests/fixture/outputFileExtension/javascript/**/input.js")]
fn fixture_output_file_extension_javascript(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");

test_fixture(
Default::default(),
&|_| {
relay(
&Config {
artifact_directory: None,
language: RelayLanguageConfig::TypeScript,
eager_es_modules: true,
output_file_extension: OutputFileExtension::JavaScript,
},
FileName::Real("file.js".parse().unwrap()),
Default::default(),
None,
None,
)
},
&input,
&output,
Default::default(),
);
}

#[testing::fixture("tests/fixture/outputFileExtension/typescript/**/input.js")]
fn fixture_output_file_extension_typescript(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");

test_fixture(
Default::default(),
&|_| {
relay(
&Config {
artifact_directory: None,
language: RelayLanguageConfig::JavaScript,
eager_es_modules: true,
output_file_extension: OutputFileExtension::TypeScript,
},
FileName::Real("file.js".parse().unwrap()),
Default::default(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const myFragment = graphql`
fragment FooFragment on Bar {
id
}
`
useQuery(graphql`
query FooQuery {
id
}
`)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import __FooFragment from "__generated__/FooFragment.graphql.js";
import __FooQuery from "__generated__/FooQuery.graphql.js";
const myFragment = __FooFragment;
useQuery(__FooQuery);
Loading

0 comments on commit dc992bb

Please sign in to comment.