Use addDependency to track metadata route file changes (#66714)

### What

Use `addDependency` to track the file path passed to
`next-metadata-route-loader`

NOTE: We cannot apply the `next-metadata-route-loader` directly to the
metatda convention source files, since the json file could be processed
by json loader (Related previous fix #62615)

### Why

Previously when we passed down the file path as argument to the loader,
which sort of breaking the caching of webpack as the actual resource
path is string, it's not tracked as a dependency. This change fixed the
bad caching issue of static metadata routes. Based on the above reason
we use `addDependency` here to track the dependency change

Closes NEXT-3521
Closes #65755
This commit is contained in:
Jiachi Liu 2024-06-11 17:19:23 +02:00 committed by GitHub
parent f6bdd11c5b
commit 73e4895dfa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 64 additions and 3 deletions

View file

@ -127,7 +127,6 @@ async function createAppRouteCode({
const isDynamicRouteExtension = pageExtensions.includes(ext)
resolvedPagePath = `next-metadata-route-loader?${stringify({
page,
filePath: resolvedPagePath,
isDynamicRouteExtension: isDynamicRouteExtension ? '1' : '0',
})}!?${WEBPACK_RESOURCE_QUERIES.metadataRoute}`

View file

@ -21,10 +21,10 @@ const cacheHeader = {
}
type MetadataRouteLoaderOptions = {
page: string
// Using separate argument to avoid json being parsed and hit error
// x-ref: https://github.com/vercel/next.js/pull/62615
filePath: string
isDynamicRouteExtension: '1' | '0'
isDynamicMultiRoute: '1' | '0'
}
export function getFilenameAndExtension(resourcePath: string) {
@ -248,6 +248,7 @@ const nextMetadataRouterLoader: webpack.LoaderDefinitionFunction<MetadataRouteLo
async function () {
const { isDynamicRouteExtension, filePath } = this.getOptions()
const { name: fileBaseName } = getFilenameAndExtension(filePath)
this.addDependency(filePath)
let code = ''
if (isDynamicRouteExtension === '1') {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -0,0 +1,52 @@
import { nextTestSetup } from 'e2e-utils'
import crypto from 'crypto'
function generateMD5(text: string) {
const hash = crypto.createHash('md5')
hash.update(text)
return hash.digest('hex')
}
describe('app dir - metadata static routes cache', () => {
const { next } = nextTestSetup({
files: __dirname,
skipStart: true,
})
it('should generate different content after replace the static metadata file', async () => {
await next.build()
const faviconBuildContent = await next.readFile(
'.next/server/app/favicon.ico.body'
)
const opengrpahImageBuildContent = await next.readFile(
'.next/server/app/opengraph-image.png.body'
)
const faviconMd5 = generateMD5(faviconBuildContent)
const opengraphImageMd5 = generateMD5(opengrpahImageBuildContent)
// Update favicon and opengraph image
const newFaviconContent = await next.readFile('app/favicon.ico.new')
await next.patchFile('app/favicon.ico', newFaviconContent)
const newOpengraphImageContent = await next.readFile(
'app/opengraph-image.png.new'
)
await next.patchFile('app/opengraph-image.png', newOpengraphImageContent)
await next.build()
const faviconBuildContentNew = await next.readFile(
'.next/server/app/favicon.ico.body'
)
const opengrpahImageBuildContentNew = await next.readFile(
'.next/server/app/opengraph-image.png.body'
)
const faviconMd5New = generateMD5(faviconBuildContentNew)
const opengraphImageMd5New = generateMD5(opengrpahImageBuildContentNew)
expect(faviconMd5).not.toBe(faviconMd5New)
expect(opengraphImageMd5).not.toBe(opengraphImageMd5New)
})
})

View file

@ -15735,6 +15735,15 @@
"pending": [],
"flakey": [],
"runtimeError": false
},
"test/production/app-dir/metadata-static-route-cache/metadata-static-route-cache.test.ts": {
"passed": [],
"failed": [
"app dir - metadata static routes cache should generate different content after replace the static metadata file"
],
"pending": [],
"flakey": [],
"runtimeError": false
}
},
"rules": {