Skip to content

Commit b8aa333

Browse files
mi-na-botGatsbyJS Bot
authored andcommitted
fix(gatsby): Fix matchpath ordering (#18478)
* Add a test that fails when a * matchpath shadows an index page. * Trailing * is removed during matchPath page weight scoring, this places glob paths at an equal level to index paths. Test for glob path prescedence now uses `toEqual` for deep object comparison. * Place all static paths before matchPaths using wildcard sort field before score. * Test case is more difficult with pages nested more deeply in matchPaths.
1 parent f5d3317 commit b8aa333

File tree

3 files changed

+140
-1
lines changed

3 files changed

+140
-1
lines changed

packages/gatsby/src/bootstrap/__tests__/__snapshots__/requires-writer.js.snap

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`requires-writer matchPath have static pages first and prefer more specific matchPaths 1`] = `
4+
Array [
5+
Object {
6+
"matchPath": "/mp1/mp2/hello",
7+
"path": "/mp1/mp2/hello",
8+
},
9+
Object {
10+
"matchPath": "/mp1/mp2",
11+
"path": "/mp1/mp2",
12+
},
13+
Object {
14+
"matchPath": "/some-page",
15+
"path": "/some-page",
16+
},
17+
Object {
18+
"matchPath": "/",
19+
"path": "/",
20+
},
21+
Object {
22+
"matchPath": "/mp1/mp2/mp3/mp4/*",
23+
"path": "/mp4",
24+
},
25+
Object {
26+
"matchPath": "/mp1/mp2/mp3/*",
27+
"path": "/mp3",
28+
},
29+
Object {
30+
"matchPath": "/mp1/mp2/*",
31+
"path": "/mp2",
32+
},
33+
Object {
34+
"matchPath": "/mp1/*",
35+
"path": "/mp1",
36+
},
37+
Object {
38+
"matchPath": "/*",
39+
"path": "/custom-404",
40+
},
41+
]
42+
`;
43+
344
exports[`requires-writer matchPath should be sorted by specificity 1`] = `
445
Array [
546
Object {
@@ -21,6 +62,19 @@ Array [
2162
]
2263
`;
2364

65+
exports[`requires-writer matchPath should have index pages with higher priority than matchPaths 1`] = `
66+
Array [
67+
Object {
68+
"matchPath": "/",
69+
"path": "/",
70+
},
71+
Object {
72+
"matchPath": "/*",
73+
"path": "/custom-404",
74+
},
75+
]
76+
`;
77+
2478
exports[`requires-writer matchPath should have static pages that live inside a matchPath 1`] = `
2579
Array [
2680
Object {

packages/gatsby/src/bootstrap/__tests__/requires-writer.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,5 +145,80 @@ describe(`requires-writer`, () => {
145145
expect(matchPaths[0].path).toBe(pages.get(`/app/clients/static`).path)
146146
expect(matchPaths).toMatchSnapshot()
147147
})
148+
149+
it(`should have index pages with higher priority than matchPaths`, async () => {
150+
const pages = generatePagesState([
151+
{
152+
path: `/`,
153+
},
154+
{
155+
path: `/custom-404`,
156+
matchPath: `/*`,
157+
},
158+
])
159+
160+
await requiresWriter.writeAll({
161+
pages,
162+
program,
163+
})
164+
165+
expect(matchPaths[0].path).toBe(pages.get(`/`).path)
166+
expect(matchPaths).toMatchSnapshot()
167+
})
168+
169+
it(`have static pages first and prefer more specific matchPaths`, async () => {
170+
const pages = generatePagesState([
171+
{
172+
path: `/`,
173+
},
174+
{
175+
path: `/custom-404`,
176+
matchPath: `/*`,
177+
},
178+
{
179+
path: `/mp4`,
180+
matchPath: `/mp1/mp2/mp3/mp4/*`,
181+
},
182+
{
183+
path: `/some-page`,
184+
},
185+
{
186+
path: `/mp1/mp2`,
187+
},
188+
{
189+
path: `/mp1/mp2/hello`,
190+
},
191+
{
192+
path: `/mp1`,
193+
matchPath: `/mp1/*`,
194+
},
195+
{
196+
path: `/mp2`,
197+
matchPath: `/mp1/mp2/*`,
198+
},
199+
{
200+
path: `/mp3`,
201+
matchPath: `/mp1/mp2/mp3/*`,
202+
},
203+
])
204+
205+
await requiresWriter.writeAll({
206+
pages,
207+
program,
208+
})
209+
210+
expect(matchPaths.map(p => p.path)).toEqual([
211+
`/mp1/mp2/hello`,
212+
`/mp1/mp2`,
213+
`/some-page`,
214+
`/`,
215+
`/mp4`,
216+
`/mp3`,
217+
`/mp2`,
218+
`/mp1`,
219+
`/custom-404`,
220+
])
221+
expect(matchPaths).toMatchSnapshot()
222+
})
148223
})
149224
})

packages/gatsby/src/bootstrap/requires-writer.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,19 @@ const getComponents = pages =>
2727
*/
2828
const getMatchPaths = pages => {
2929
const createMatchPathEntry = (page, index) => {
30-
let score = page.matchPath.replace(/\/$/, ``).split(`/`).length
30+
let score = page.matchPath.replace(/[/][*]?$/, ``).split(`/`).length
31+
let wildcard = 0
32+
3133
if (!page.matchPath.includes(`*`)) {
34+
wildcard = 1
3235
score += 1
3336
}
3437

3538
return {
3639
...page,
3740
index,
3841
score,
42+
wildcard,
3943
}
4044
}
4145

@@ -74,6 +78,12 @@ const getMatchPaths = pages => {
7478

7579
return matchPathPages
7680
.sort((a, b) => {
81+
// Paths with wildcards should appear after those without.
82+
const wildcardOrder = b.wildcard - a.wildcard
83+
if (wildcardOrder !== 0) {
84+
return wildcardOrder
85+
}
86+
7787
// The higher the score, the higher the specificity of our matchPath
7888
const order = b.score - a.score
7989
if (order !== 0) {

0 commit comments

Comments
 (0)