I recently started using gatsby-plugin-typescript to convert a project to TypeScript. It's been working fine so far, but when I converted a file containing a graphql-tag, I got the following errow when building:
error Building static HTML for pages failed
See our docs page on debugging HTML builds for help https://goo.gl/yL9lND
294 | }
295 |
> 296 | export const pageQuery = graphql`
| ^
297 | query IndexPageQuery {
298 | hero: contentfulHero(contentfulid: { eq: "main-hero" }) {
299 | heading
WebpackError: graphql is not defined
- index.tsx:296 Object.__assign.__assign.Object.assign.i
src/pages/index.tsx:296:14
- sync-requires.js:10 Object.exports.__esModule
.cache/sync-requires.js:10:52
- static-entry.js:8 Object.<anonymous>
.cache/static-entry.js:8:1
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
I _assume_ this is because the graphql-tags are not extracted as they should be, although I'm not sure.
I'm running the latest version of Gatsby as of writing this (1.9.127) on Arch Linux with node v9.2.0. Here are my relevant files asked for in CONTRIBUTING.md:
gatsby-config.js:
module.exports = {
siteMetadata: {
title: `Project`
},
plugins: [
{
resolve: `gatsby-plugin-typescript`,
options: {
transpileOnly: false,
compilerOptions: {
target: "es5",
jsx: `react`
}
}
},
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: `0az5a6x9rmhy`,
accessToken: `dac10b17c98d724d640eba63ba8896aced86c3813a9c8ef8b00cae10830f01d9`
}
}
]
};
package.json:
{
"name": "gatsby-starter-default",
"description": "Gatsby default starter",
"version": "1.0.0",
"author": "Kyle Mathews <[email protected]>",
"dependencies": {
"axios": "^0.16.2",
"flexbox-react": "^4.4.0",
"font-awesome": "^4.7.0",
"gatsby": "^1.8.12",
"gatsby-link": "^1.6.8",
"gatsby-plugin-react-helmet": "^1.0.3",
"gatsby-plugin-typescript": "^1.4.10",
"gatsby-source-contentful": "^1.3.7",
"normalize.css": "^7.0.0",
"react-dropdown": "^1.3.0",
"react-markdown": "^3.0.1",
"react-slider": "^0.9.0",
"recompose": "^0.25.0",
"reset-css": "^2.2.1",
"swe-validation": "^1.0.1",
"typescript": "^2.6.1"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"main": "n/a",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop --host localhost",
"develop-with-polling": "CHOKIDAR_USEPOLLING=true CHOKIDAR_INTERVAL=1000 yarn develop",
"format": "prettier --write 'src/**/*.js'",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"@types/react": "^15.6.0",
"@types/react-dom": "^15.5.0",
"@types/recompose": "^0.24.3",
"prettier": "^1.8.2"
}
}
gatsby-node.js:
const _ = require(`lodash`);
const Promise = require(`bluebird`);
const path = require(`path`);
// Implement the Gatsby API “createPages”. This is
// called after the Gatsby bootstrap is finished so you have
// access to any information necessary to programatically
// create pages.
const addContentPages = (graphql, createPage) =>
new Promise((resolve, reject) => {
graphql(
`
{
allContentfulContentPage(limit: 1000) {
edges {
node {
id
slug
}
}
}
}
`
).then(result => {
if (result.errors) {
reject(result.errors);
}
const productTemplate = path.resolve(`./src/templates/contentPage.js`);
result.data.allContentfulContentPage.edges.map(edge => {
createPage({
path: `/${edge.node.slug}/`,
component: productTemplate,
context: {
id: edge.node.id
}
});
});
resolve();
});
});
const addSimplePages = (graphql, createPage) =>
new Promise((resolve, reject) => {
graphql(
`
{
allContentfulSimplePage(limit: 1000) {
edges {
node {
id
slug
}
}
}
}
`
).then(result => {
if (result.errors) {
reject(result.errors);
}
const productTemplate = path.resolve(`./src/templates/simplePage.js`);
result.data.allContentfulSimplePage.edges.map(edge => {
createPage({
path: `/${edge.node.slug}/`,
component: productTemplate,
context: {
id: edge.node.id
}
});
});
resolve();
});
});
exports.createPages = ({ graphql, boundActionCreators }) => {
const { createPage } = boundActionCreators;
return addContentPages(graphql, createPage).then(x =>
addSimplePages(graphql, createPage)
);
};
exports.modifyWebpackConfig = ({ config }) => {
config.merge({
resolve: {
alias: {
Theme: path.resolve(__dirname, "src/theme/index.ts")
}
}
});
return config;
};
You should be able to solve this by creating a declarations.d.ts file in your ./src folder and add the following:
declare const graphql: (query: TemplateStringsArray) => void;
Probably not ideal, but at least this is the way they solved the issue in the gatsby-typescript-starter:
https://github.com/fabien0102/gatsby-starter
@cfowlerdev That does not do the trick, unfortunately. I had to do that to solve TypeScript complaining about graphql, but the problem I'm having is that the graphql statement is not removed from the source file, so the page crashes at runtime (with gatsby develop, or build time wiht gatsby build) because graphql is undefined.
Ah, I figured out what's going on! babel-plugin-extract-graphql is looking for TaggedTemplateExpression AST nodes, but tsc compiles them into helper functions. I'm trying to figure out what can be done about it (messing around with compiler options), but at least I know what's wrong now.
Okay, needed to change target to es2015 in gatsby-config.js. Now it works fine. Maybe babel-plugin-extract-graphql should be updated to extract all uses of global graphql or something similar? I'm not sure what the best course of action would be here.
Yes, looks like it's down to your compiler options. Have you tried changing the target from "es5" to "esnext" in your typescript options in gatsby-config.js?
Just did a quick test and was able to reproduce your issue by setting the target to es5. Switched back to esnext and it works fine.
ah! you beat me to it :) good to hear you solved it
By seconds! 😅 Thanks for helping out, regardless!
From what I saw, when you set the typescript compiler to target esnext, minification doesn't work properly.
Due to the high volume of issues, we're closing out older ones without recent activity. Please open a new issue if you need help!
Most helpful comment
You should be able to solve this by creating a declarations.d.ts file in your ./src folder and add the following:
declare const graphql: (query: TemplateStringsArray) => void;Probably not ideal, but at least this is the way they solved the issue in the gatsby-typescript-starter:
https://github.com/fabien0102/gatsby-starter