中继编译器无法在 Typescript 中提取和使用 graphql 查询

Posted

技术标签:

【中文标题】中继编译器无法在 Typescript 中提取和使用 graphql 查询【英文标题】:relay-compiler unable to extract and use graphql queries in Typescript 【发布时间】:2019-09-14 03:51:17 【问题描述】:

我尝试通过Typescript react starter 使用中继,但遇到了多个问题。

似乎 babel-plugin-relay 无法感知中继编译器提取的 graphql 语句。这是我的编译器脚本

"relay": "relay-compiler --src ./src --schema ./src/schema.graphql --extensions=tsx --watchman false".

.babelrc


   "babel": 
   "presets": [
      "react-app"
   ],
   "plugins": [
     "relay"
   ]

这是我的错误,提示 babel 转译存在问题

graphql: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used verbatim as `graphql`.

【问题讨论】:

【参考方案1】:

基本上这个问题解决了在转换过程中从 typescript 中提取 GraphQL 标签。由于在这些 PR #1710 和 #2293 中工作,我找到了解决方案。

步骤如下:

修改 webpack 配置以包含一个 babel loader(typescript starter 只有一个 ts-loader)。

    ...
    test: /\.(ts|tsx)$/,
    include: paths.appSrc,
    exclude: /node_modules/,
    use: [
        loader: 'babel-loader' ,
       
         loader: require.resolve('ts-loader'),
         options: 
            transpileOnly: true,
         ,
       ,
    ],
    ...

将tsconfig中的targetmodule配置改为es2015

...
"target": "es2015",
"module": "es2015",
...

添加relay-compiler-language-typescript

yarn add relay-compiler-language-typescript -D

同时添加babel-plugin-transform-es2015-modules-commonjs

yarn add babel-plugin-transform-es2015-modules-commonjs -D

由于现在我们的目标是 es2015,所以需要这个插件来支持 ES 模块 importexport 语句。

还有一个编译graphql语句的脚本

"relay": "relay-compiler --src ./src --schema src/schema.graphql --language typescript --artifactDirectory ./src/__generated__ --watch"

将中继插件指向.babelrc中使用上述命令生成的工件

"plugins": [
    "transform-es2015-modules-commonjs",
    ["relay",  "artifactDirectory": "./src/__generated__" ],
 ],

【讨论】:

这样做的问题是现在不能使用使用commonjs模块系统的模块。例如,现在 typescript 对我大喊它找不到 antd 模块:import Form, Input, Button from 'antd' 为了解决这个问题,我不得不在 tsconfig.json 中设置 "moduleResolution": "node"【参考方案2】:

我的 .babelrc 是这样的


    "plugins": [
        [
            // Please note that the "relay" plugin should run before other plugins or presets to ensure the graphql template literals are correctly transformed. See Babel's documentation on this topic.
            "relay",
            
                "artifactDirectory": "./src/__generated__"
            
        ],
        [
            "transform-es2015-modules-commonjs",
            
                "allowTopLevelThis": true
            
        ]
    ]

按照这里的配置步骤https://github.com/relay-tools/relay-compiler-language-typescript#typescript

这会将您链接到 babel docs https://babeljs.io/docs/en/babel-plugin-transform-es2015-modules-commonjs/

这似乎有效。我的 npm 脚本是

"relay": "relay-compiler --src ./src --schema ./data/schema.graphql --language typescript --artifactDirectory ./src/__generated__"

并且 tsconfig.json 包含这个

    "target": "es2015",
    "module": "es2015",

更新

我必须按照此处https://create-react-app.dev/docs/adding-relay/ 的描述安装 babel-plugin-relay

并为它破解打字稿类型https://github.com/DefinitelyTyped/DefinitelyTyped/issues/35707

【讨论】:

以上是关于中继编译器无法在 Typescript 中提取和使用 graphql 查询的主要内容,如果未能解决你的问题,请参考以下文章

Typescript中继承的父类中的参数是啥?

如何在 TypeScript 中继承 PromiseLike 接口?

如何使用带有 Typescript 的泛型将中继(graphql)连接映射到边缘节点

Typescript Mixins 在编译器中无法按预期工作

无法在 Visual Studio 2012 中编译 TypeScript 文件

构建时出现 TypeScript 错误,因为我导入提取的 .graphql 文件并且无法解析类型