Skip to content
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

fix(gatsby): correctly inject static query in theme components #10786

Merged
merged 4 commits into from
Jan 4, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
jest.mock(`glob`, () => {
const sync = jest.fn().mockImplementation(() => [])
return {
sync,
}
})
const path = require(`path`)
const glob = require(`glob`)
const { resolveThemes, Runner } = require(`../query-compiler`)

const base = path.resolve(``)

describe(`Runner`, () => {
beforeEach(() => {
glob.sync.mockClear()
})

it(`returns a file parser instance`, async () => {
const runner = new Runner(base, [], {})

const parser = await runner.parseEverything()

expect(parser).toEqual(new Map())
})

describe(`expected directories`, () => {
it(`compiles src directory`, async () => {
const runner = new Runner(base, [], {})

await runner.parseEverything()

expect(glob.sync).toHaveBeenCalledWith(
expect.stringContaining(path.join(base, `src`)),
expect.any(Object)
)
})

it(`compiles fragments directory`, async () => {
const runner = new Runner(base, [], {})

await runner.parseEverything()

expect(glob.sync).toHaveBeenCalledWith(
expect.stringContaining(path.join(base, `src`)),
expect.any(Object)
)
})

it(`compiles themes directory(s)`, async () => {
const theme = `gatsby-theme-whatever`
const runner = new Runner(base, [path.join(`node_modules`, theme)], {})

await runner.parseEverything()

expect(glob.sync).toHaveBeenCalledWith(
expect.stringContaining(path.join(base, `node_modules`, theme)),
expect.any(Object)
)
})
})
})

describe(`resolveThemes`, () => {
it(`returns empty array if zero themes detected`, () => {
;[
[],
[{ resolve: path.join(base, `gatsby-plugin-whatever`) }],
undefined,
].forEach(testRun => {
expect(resolveThemes(base, testRun)).toEqual([])
})
})

it(`returns plugins matching gatsby-theme prefix`, () => {
const theme = `gatsby-theme-example`
expect(
resolveThemes(base, [
{
resolve: path.join(base, `gatsby-theme-example`),
},
])
).toEqual([theme])
})

it(`handles scoped packages`, () => {
const theme = `@dschau/gatsby-theme-example`

expect(
resolveThemes(base, [
{
resolve: path.join(base, theme),
},
])
).toEqual([theme])
})
})
47 changes: 31 additions & 16 deletions packages/gatsby/src/internal-plugins/query-runner/query-compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,24 @@ const validationRules = [
let lastRunHadErrors = null
const overlayErrorID = `graphql-compiler`

const resolveThemes = (base, plugins = []) =>
plugins.reduce((merged, plugin) => {
if (plugin.resolve.includes(`gatsby-theme-`)) {
merged.push(path.relative(base, plugin.resolve))
}
return merged
}, [])

class Runner {
baseDir: string
base: string
additional: string[]
schema: GraphQLSchema
errors: string[]
fragmentsDir: string

constructor(baseDir: string, fragmentsDir: string, schema: GraphQLSchema) {
this.baseDir = baseDir
this.fragmentsDir = fragmentsDir
constructor(base: string, additional: string[], schema: GraphQLSchema) {
this.base = base
this.additional = additional
this.schema = schema
}

Expand All @@ -91,14 +100,20 @@ class Runner {
}

async parseEverything() {
// FIXME: this should all use gatsby's configuration to determine parsable
// files (and how to parse them)
let files = glob.sync(`${this.fragmentsDir}/**/*.+(t|j)s?(x)`, {
nodir: true,
})
files = files.concat(
glob.sync(`${this.baseDir}/**/*.+(t|j)s?(x)`, { nodir: true })
)
const filesRegex = `/**/*.+(t|j)s?(x)`
let files = [`${this.base}/src`, `${this.base}/.cache/fragments`]
.concat(
this.additional.map(additional => path.join(this.base, additional))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This presumes all the same directory (e.g. node_modules/gatsby-theme, or plugins/gatsby-theme)... not sure if/how monorepos would work, so that's a wrinkle to consider.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Themes need an index.js because they function as plugins so I think we can use path.dirname(require.resolve(theme)) to get the correct base location

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like an easy fix--thanks!

)
.reduce(
(merged, base) =>
merged.concat(
glob.sync(`${base}${filesRegex}`, {
nodir: true,
})
),
[]
)
files = files.filter(d => !d.match(/\.d\.ts$/))
files = files.map(normalize)

Expand Down Expand Up @@ -217,14 +232,14 @@ class Runner {
return compiledNodes
}
}
export { Runner }
export { Runner, resolveThemes }

export default async function compile(): Promise<Map<string, RootQuery>> {
const { program, schema } = store.getState()
const { program, schema, plugins } = store.getState()

const runner = new Runner(
`${program.directory}/src`,
`${program.directory}/.cache/fragments`,
program.directory,
resolveThemes(program.directory, plugins),
schema
)

Expand Down