New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Templated string not interperted in builds #5069
Comments
This sounds like a cool feature but it's not something we support right now. We don't "run" any code in the graphql queries. We just extract the query and then run them. If this is something you want to add support for, I'd love to see an RFC on how the feature would work https://github.com/gatsbyjs/rfcs |
Too bad, I'll have a look at writing a RFC for it. |
Yeah, in gatsby-node.js, it is just a function call. For component queries we actually extract the string and then run. We could look into evaluating the string first before running it as a query but we'd need to think about the implications of doing that. |
babel does offer some amount of static evaluation if interpolations can be determined at compile time. It doesn't help this particular case but it might useful in other cases where you want to store a static value in a variable for using in the query and component. we use it in const margin = 10;
const height = 50;
const bottom = height + margin;
const styles = css`
.box {
height: ${height}px;
margin-bottom: ${margin}px;
}
.footer {
position: absolute;
top: ${bottom}px;
}
` |
Okay, I've implemented something in my local version of gatsby: By changing: gatsby/packages/gatsby/src/utils/babel-plugin-extract-graphql.js Lines 10 to 18 in 5b1dc1c
To: let text
if (quasis.length !== 1) {
import generate from 'babel-generator'
text = eval(generate(path.node.quasi).code)
}else{
text = quasis[0].value.raw
} it will now generate code for non simple ast's (more than one quasi, almost always indicating some if's) and eval it. There are some problems with this, for example it will execute the code in context of the babel plugin, not the original code. Variables and functions declared somewhere else in the file will not be compiled and thus not be executed. I'll write this all up in a RFC, but in the meantime I'll be using this. |
@jquense I just tested the constant variable placement, and this unfortunatly also doesn't work. |
It works for statically determinable values, since all that's needed is the AST, but yeah like i said it doesn't help your case since it's not statically determinable. Generally, I don't think think a feature that requires us to eval the code is good idea, it's never going to be safe, and in most cases would require that the entire tree from that file on is compiled via webpack. You'd need something really advanced and fancy like |
The current implementation of how queries are parsed doesn't allow the statically determinable values. It would be possible when parsing the whole AST but that's not being done atm. As said before I'll write this all up in a RFC so we can discuss this feature there and I'm going to close this issue since it's not a real issue anymore |
Not quite sure what you mean there, the whole ast is being generated for the file, its a babel plugin, so you really don't have a choice there.
|
If i understood the code correctly it only get's information about the tag and not it's dependencies in the AST. So it parses the whole AST, but then only passes one part of it to the graphql handling function. Correct me if i'm wrong. I Don't know what benefits switching to babel from babylon would provide, but if this would solve some problems like this it would be really nice :) |
Given that this isn't possible, can anyone suggest a way of getting a value from a config file into the query? I have a user config file where a date format can be defined:
I had hoped I could import the config file and interpolate the value, but this doesn't work:
I need this string in multiple queries, but at the moment it seems the only way of getting it into the query is via the |
As mentioned on #10163, I wonder why string interpolation, at least for things like env variables or constant is not simply allowed? It might be unsafer, but much more flexible and after all, a decision of the developer to actively use it. |
@hanoii it is a technical limitation, it's not simply a switch that can be turned on. |
@jgierer12 I think that I am trying to imply (with not enough in-depth knowledge so apologize there) is what @KyleAMathews said on #5069 (comment):
So not saying is a switch, just saying that the above is something that kind of makes sense to me. |
By the way, I think you can kind of achieve this already using import { graphql } from "gatsby"
import codegen from "codegen.macro"
export const query = codegen`
const query = \`
query myQuery {
allMarkdownRemark(
filter: {
fileAbsolutePath: { regex: "/.*/blogs/.*/" }
\${ process.env.NODE_ENV === "production" ? ", { frontmatter: { published: { eq: true } } }" : "" }
},
) {
edges {
node {
id
}
}
}
}
\`
module.exports = "graphql\`" + query + "\`"
` (Full disclosure: I haven't tested this in any way, there might well be some missing brackets/quotes) This isn't perfect (no access to variables outside the preval snippet, lots of boilerplate code, no syntax highlighting). But it should work reasonably well as a workaround. Edit: Actually, |
@jgierer12 Thanks a lot for this tip. I tried a lot of things with preval and then saw your edit. I couldn't make it work and I think it's all part of the same thing, in which file-parser takes care of a lot of stuff before even compiling, but I am just diving into this so it might take a bit until I wrap my head properly around all this. I tried with codegen and I got this:
You seem more versed that I am on this particular thing. If you happen to spare a few mins and can try this out to see if it works it'll help me a lot. It doesn't have to be env or anything, just any other variable. I actually tried it with a static query (the same that worked without it) and it didn't work either. |
Hmm, it seems like Gatsby doesn't even transform the code before extracting queries. @KyleAMathews do you know more about this (is Gatsby supposed to run babel transformations before extracting the GraphQL queries)? |
so yeah, @jgierer12 showed exactly the use case I would have liked to change that query - so, really, it's just not possible to add a filter when you are in development mode as opposed to production (or vice versa)? |
Would be great to have string interpolation. |
There is a rfc open to create a new tag for this gatsbyjs/rfcs#3. If you want this feature we could discuss workings there and maybe get them to accept the rfc so we can start working on the feature. |
Hi, I think I am not really understanding the recommended way for adding new images to a gatsby project. I scaffolded a new project, and the only example image file look like this:
I wanted to make a generic "Image" component that takes the filename as a parameter:
but this is giving me the error:
So, I am confused now... I am supposed to make a new js file for every image that I add to my project? Seems very repetitive, but maybe it is necessary for the way the images are loaded? Anyway, some clarification on this would help me out a lot. Thanks! |
I think GraphQL queries should not use JS template string syntax to not mislead developer that he can use any variable interpolation. It is just wrong language feature used for this kind of technological feature. |
@gitowiec Yes, ideal would be that it accepts a template string as an argument where the developers can interpolate in and allow multiple queries to exist in the same page. Like I would prefer having all getter queries in one file and make changes only to that file if I need to. Queries inside a component makes components ugly and things a little bit hard to maintain. |
Any update on this? |
@gersongams I've made a Pr in the RFC for gatsby, It was not accepted. So it won't be implemneted. |
Description
When using a templated string to filter for published articles on production builds like this
It gives the following error:
Steps to reproduce
Build a page with a query that uses a templated string literal.
Expected result
It should first interpret the string literal, and after that make it a graphql fragment
Actual result
It throws an error saying substitution not allowed.
Environment
npm list gatsby
): gatsby@1.9.250gatsby --version
): 1.1.50The text was updated successfully, but these errors were encountered: