Closed estaub closed 6 years ago
I am also having the same issue. I have also tried workarounds mentioned in #42 and here #59 . Also tried adding custom module declaration for gql files and playing around with alternatives.
Workarounds and outputs are like these:
query.gql
import query from './query.gql'
/* =>
Ts output: `error TS2307: Cannot find module './query.gql'.`
Browser console output: -
*/
index.t.ds
// index.d.ts
declare module "*.gql" {
const content: any;
export default content;
}
// component.tsx
import query from './query.gql'
/* =>
Ts output: Fine / No error
Browser console output: browser.js:40 Uncaught Error: Argument of undefined passed to parser was not a valid GraphQL DocumentNode. You may need to use 'graphql-tag' or another method to convert your operation into a document
*/
import = require
syntax.// index.d.ts
// // ...same as 2
// component.tsx
import query = require('./query.gql')
/* =>
Ts output: `error TS2345: Argument of type 'typeof "*.gql"' is not assignable to parameter of type 'DocumentNode'.
Property 'kind' is missing in type 'typeof "*.gql"'.`
Browser console output: Fine / No error (actually works)
*/
DocumentNode
from graphql typings.// index.d.ts
import {
DocumentNode
} from 'graphql'
declare module "*.gql" {
const content: DocumentNode;
export default content;
}
// component.tsx
import query = require('./query.gql')
/* =>
Ts output: `error TS2307: Cannot find module './query.gql'.`
Browser output: -
*/
I can live with typescript error Argument of type 'typeof "*.gql"' is not assignable
since it does not break actual usage, but it would be great to fix that in some way.
I have tried both "allowSyntheticDefaultImports": true
and delete query['default']
workarounds, could not get an errorless flow for both typescript and browser usage.
I found that this works:
// graphql.d.ts file
declare module '*.graphql' {
import {DocumentNode} from 'graphql';
const value: DocumentNode;
export = value;
}
then, when I need to import *.graphql
/// <reference path="./graphql.d.ts" />
import schema = require('./schema.graphql');
Changing the solution by @ddetkovs to
// graphql.d.ts file
declare module '*.graphql' {
import {DocumentNode} from 'graphql';
const value: DocumentNode;
export default value;
}
/// <reference path="./graphql.d.ts" />
import schema from './schema.graphql';
works for ES2015 import.
@Aides359 graphql loader exports schema like this:
module.exports = doc;
This module is then resolved with webpack and since you're using es2015 import syntax it tries to access its default member, which is undefined, thus causing a runtime error.
I get the following generated code:
var graphql_tools_1 = __webpack_require__(6);
var schema_graphql_1 = __webpack_require__(4);
var resolvers_1 = __webpack_require__(1);
exports.default = graphql_tools_1.makeExecutableSchema({ typeDefs: [schema_graphql_1.default], resolvers: resolvers_1.default });
Also, typescript handbook says this:
When importing a module using export =, TypeScript-specific import module = require("module") must be used to import the module.
@ddetkovs odd, my described setup works in my project, without any runtime errors :thinking: I'll check the generated code and see how it behaves, however I probably won't find time to do so before next monday.
Any updates on this?
unfortunately i dont know enough about typescript to know what the solution space for this issue might be like. if there's any chance someone can send me a repo (or just some code) that exhibits exactly this issue, i can look into figuring out how to resolve this
@ddetkovs this fell of my radar, however I have now taken a look at my generated output.
While I don't know about makeExecutableSchema
as I am currently only using it to write queries for me the generated code is
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__request_foo_graphql__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__request_foo_graphql___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4__request_foo_graphql__);
apollo.watchQuery({
query: __WEBPACK_IMPORTED_MODULE_4__request_foo_graphql___default
})
which works just fine.
@Aides359 what I meant is when graphql-tag/loader compiles your query, it exports it as:
module.exports = doc
here
when you do: import schema from './schema.graphql';
, you import default property of the module, but exported doc doesn't have it, so it fails.
This works too:
import * as schema from './schema.graphql';
This solution works for me. It's similar to what @ddetkovs posted earlier but allows you to use the import
syntax and doesn't require using /// <reference path="..." />
All of my .graphql
files are in a single folder so I could add an index.d.ts
in that folder with the following
declare module '*.graphql' {
import {DocumentNode} from 'graphql';
const value: DocumentNode;
export = value;
}
Having all of the .graphql
files in a single directory and naming it index.d.ts
avoids the need to add /// <reference path="./graphql.d.ts" />
in other files.
I can then import using import * as MyQuery from "../graphql/MyQuery.graphql"
Thanks to @ddetkovs, @Aides359
Any updates here?
@gustavoalfaro Solution by @Aides359 works for me.
@nitingupta910 Changing this: import MyQuery from "../graphql/MyQuery.graphql"
for this: import * as MyQuery from "../graphql/MyQuery.graphql"
doesn't work for me
@gustavoalfaro
Did you include the declare module '*.graphql'
... declaration suggested above? I figure that with 20 up-votes, it's probably worth a shot!
What error do you see?
Facing the same issue. Any update on this?
again, unfortunately i dont know enough about typescript in order to figure out what i can do here. please open a PR to provide better documentation about TypeScript usage if that is the general consensus on how to avoid other folks getting hit by this.
closing for now, but please re-open if there's more to discuss.
+1
Could anyone having issues with this please post the error message they're getting? I had trouble implementing the above solution because I didn't have the import { DocumentNode } from "graphql"
inside the declare module
..
Could someone upload a reproducible example of it working? I am getting this error:
[server] Module build failed (from ./node_modules/graphql-tag/loader.js):
[server] GraphQLError: Syntax Error: Unexpected Name "module"
// Module.tsx
/// <reference path="../../types/graphql.d.ts" />
import getStatus from './NetworkQueries.graphql'
// const getStatus = require('./NetworkQueries.gql')
// NetworkQueries.graphql
query {
networkStatus @client {
isConnected
}
}
what is the current status on this issue? webpack ts loader compile without any problem my import of graphql files using like
import * as type from 'type.grpahql';
// it get me the files like I want
// but gets my this error on console and vscode [ts] Cannot find module './type.graphql'
I think this is more in tsconfig problem if anyone can get me some guide I will be great
Solved just add to tsconfig includes the d.ts definition of @buggy thanks
@buggy thanks. After add d.ts,tslint
still throw some error:
My case is:
import * as Q from 'gqlMod/queries/library.gql';
import * as M from 'gqlMod/mutations/library.gql';
//...
//...
export default compose(
graphql(Q.CART, {
props: ({ data: { cart } }) => {
return {
cart
};
}
}),
graphql(M.REMOVE_ALL_FROM_COUNT, { name: 'removeAllFromCart' }),
graphql(M.ADD_TO_CART, { name: 'addToCart' }),
graphql(M.REMOVE_FROM_CART, { name: 'removeFromCart' }),
graphql(M.REMOVE_COUNT_FROM_CART, { name: 'removeCountFromCart' })
)(Cart);
tslint
give me some errors:
[ts] Property 'CART' does not exist on type 'DocumentNode'.
[ts] Property 'REMOVE_ALL_FROM_COUNT' does not exist on type 'DocumentNode'.
...
So I change the d.ts
like this:
declare module '*.gql' {
import { DocumentNode } from 'graphql';
const value: {
CART: DocumentNode;
REMOVE_ALL_FROM_COUNT: DocumentNode;
ADD_TO_CART: DocumentNode;
REMOVE_FROM_CART: DocumentNode;
REMOVE_COUNT_FROM_CART: DocumentNode;
};
export = value;
}
It works fine. tslint
error gone. It's a little more complex for adding definition for each query
.
So change d.ts
again like this:
declare module '*.gql' {
import { DocumentNode } from 'graphql';
const value: {
[key: string]: DocumentNode;
};
export = value;
}
@gustavoalfaro
Did you include the
declare module '*.graphql'
... declaration suggested above? I figure that with 20 up-votes, it's probably worth a shot!What error do you see?
i got the imported module is just a string? just like that "/static/media/postsByUser.79323037.graphql"
@buggy thank you for the solution!
I'm still having an issue because my GraphQL client (Apollo) is expecting a object typed GraphQLSchema by using your method I just get a DocumentNode.
ts]
Argument of type '{ schema: DocumentNode; }' is not assignable to parameter of type 'Options'.
Types of property 'schema' are incompatible.
Type 'DocumentNode' is not assignable to type 'GraphQLSchema'.
Property 'astNode' is missing in type 'DocumentNode'.
(property) schema: DocumentNode
Do you know how to fit to this requirement? Thank you!
Note: I tried to set GraphQLSchema instead of DocumentNode in the index.d.ts
but it doesn't work
@gustavoalfaro Did you include the
declare module '*.graphql'
... declaration suggested above? I figure that with 20 up-votes, it's probably worth a shot! What error do you see?i got the imported module is just a string? just like that "/static/media/postsByUser.79323037.graphql"
@annguyen0505 I got the same problem and you probably aren't using graphql-tag/loader in your webpack configuration.
Check out react-app-rewired with react-app-rewire-graphql-tag so you don't need to eject your react app (assuming you have a project created by create-react-app
).
@nemcek Can you elaborate on “you probably aren't using graphql-tag/loader in your webpack configuration”?
My webpack configuration looks just like:
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader',
}
I’ve added the following as per this comment:
declare module '*.graphql' {
import {DocumentNode} from 'graphql';
const value: DocumentNode;
export = value;
}
Which does get rid of my compile-time errors, but I still get hit with the following at runtime:
GraphQLError: Syntax Error: Unexpected Name "module"
Any thoughts would be appreciated, I really have no idea how to get past this.
The solution works for me, but does anyone have a solution that works across many directories? My codebase is based on a module structure so the graphql tags are not flat in a single directory.
I've tried the solutions listed here and I simply cannot get this to work. I receive the following error, no matter what:
src/modules/auth/index.ts(2,27): error TS2307: Cannot find module './schema.graphql'.``
I have tried placing the graphql.d.ts
file within the same directory as the .graphql file, at the src
level, at the project root. None have altered a single thing. It's as if TS isn't even seeing the .d.ts file.
Here is the tsconfig:
"compilerOptions": {
"lib": ["es2017", "esnext.asynciterable", "dom"],
"target": "es2017",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"outDir": "dist",
"typeRoots": ["node_modules/@types"],
"paths": {
"@lib/*": ["./lib/*"],
"@models/*": ["./models/*"],
"@modules/*": ["./modules/*"]
},
"baseUrl": "./src/",
"allowSyntheticDefaultImports": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
@jchapple it would help if you post a link to your file structure (e.g. output of find .
) to a pastebin, and also mention your TypeScript version. But anyway, I think the typeRoots
line in your tsconfig might be the source of this problem.
I don't see it mentioned here, and this is the top google result for this problem. So FYI, graphql-code-generator
has a plugin to generate these module definitions. It solved the problem for me.
https://graphql-code-generator.com/docs/plugins/typescript-graphql-files-modules
Faced the problem with importing .gql
across many directories (same as @switz has mentioned).
Solved it with global.d.ts
. For example, let it be placed in src
folder
// src/global.d.ts
declare module '*.gql' {
import { DocumentNode } from 'graphql';
const value: DocumentNode;
export = value;
}
Be sure that src
folder is in include
section of your tsconfig.json
// tsconfig.json
{
// ...
"include": ["src/**/*.ts"]
}
Thanks to @buggy and others.
I'm facing the same issue, any ideas?
tsconfig.json
{
"compilerOptions": {
"lib": ["es2017"],
"moduleResolution": "node",
"noUnusedLocals": false,
"noUnusedParameters": true,
"sourceMap": true,
"target": "es2017",
"outDir": "lib"
},
"exclude": ["node_modules"]
}
webpack.config.js
const path = require('path')
const slsw = require('serverless-webpack')
module.exports = {
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
entry: slsw.lib.entries,
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx', '.json', '.ts', '.tsx', '.mjs', '.gql', '.graphql']
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, '.webpack'),
filename: '[name].js'
},
target: 'node',
module: {
rules: [
// all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
{ test: /\.(tsx?|mjs)$/, loader: 'ts-loader' },
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader'
}
]
}
}
usage:
import typeDefs from './schema.graphql'
if you having trouble importing gql files with jest I solved by using @ddetkovs solution plus adding this to jest config.
transform: { '^.+\\.(gql|graphql)$': 'jest-transform-graphql', ... }
more info here https://github.com/remind101/jest-transform-graphql
Hope this helps.
I used code from @buggy:
declare module '*.graphql' {
import { DocumentNode } from 'graphql';
const value: DocumentNode;
export = value;
}
I put this code into index.d.ts
file into my src/@types
folder. Then I add this folder to my typeRoots
setting in tsconfing.json
file:
"typeRoots": ["./src/@types"]
This solution works for me for all .graphql
files inside my src
folder.
This is a reopen of https://github.com/apollographql/graphql-tag/issues/42 .
Nothing has changed, it's just that the presence of a workaround is not a fix.
As described before, attempts to import a graphql module result in
Cannot find module...
. Usingrequire
instead ofimport
, eg:const query = require('gql/Query.gql');
works fine... up to a point. Somewhere, the Apollo
graphql
decorator performs a deep copy of the query Thequery
DocumentNode returned above includes adefault
element that has itself as a property. As a result, the deep copy blows out with a soft stack overflow. So the full workaround is:const query = require('gql/Query.gql'); delete query['default']
It's possible that the
default
problem is dependent on thetsconfig.json
setting:"allowSyntheticDefaultImports": true
I need it for other reasons, and was unable to easily test with it turned off.