Skip to content

Commit

Permalink
Add initial standalone build handling (#31003)
Browse files Browse the repository at this point in the history
* Add initial standalone handling

* apply suggestions

* Apply suggestions from code review

Co-authored-by: Steven <steven@ceriously.com>
  • Loading branch information
ijjk and styfle committed Nov 9, 2021
1 parent 31985c5 commit eb7b401
Show file tree
Hide file tree
Showing 8 changed files with 233 additions and 99 deletions.
47 changes: 47 additions & 0 deletions packages/next/build/index.ts
Expand Up @@ -91,6 +91,7 @@ import {
printTreeView,
getCssFilePaths,
getUnresolvedModuleFromError,
copyTracedFiles,
isReservedPage,
isCustomErrorPage,
} from './utils'
Expand All @@ -103,6 +104,7 @@ import isError, { NextError } from '../lib/is-error'
import { TelemetryPlugin } from './webpack/plugins/telemetry-plugin'
import { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack'
import { recursiveCopy } from '../lib/recursive-copy'

export type SsgRoute = {
initialRevalidateSeconds: number | false
Expand Down Expand Up @@ -552,6 +554,7 @@ export default async function build(
path.relative(distDir, manifestPath),
BUILD_MANIFEST,
PRERENDER_MANIFEST,
path.join(SERVER_DIRECTORY, MIDDLEWARE_MANIFEST),
hasServerComponents
? path.join(SERVER_DIRECTORY, MIDDLEWARE_FLIGHT_MANIFEST + '.js')
: null,
Expand Down Expand Up @@ -1362,6 +1365,23 @@ export default async function build(
'utf8'
)

const outputFileTracingRoot =
config.experimental.outputFileTracingRoot || dir

if (config.experimental.outputStandalone) {
await nextBuildSpan
.traceChild('copy-traced-files')
.traceAsyncFn(async () => {
await copyTracedFiles(
dir,
distDir,
pageKeys,
outputFileTracingRoot,
requiredServerFiles.config
)
})
}

const finalPrerenderRoutes: { [route: string]: SsgRoute } = {}
const tbdPrerenderRoutes: string[] = []
let ssgNotFoundPaths: string[] = []
Expand Down Expand Up @@ -1957,6 +1977,33 @@ export default async function build(
return Promise.reject(err)
})

if (config.experimental.outputStandalone) {
for (const file of [
...requiredServerFiles.files,
path.join(config.distDir, SERVER_FILES_MANIFEST),
]) {
const filePath = path.join(dir, file)
await promises.copyFile(
filePath,
path.join(
distDir,
'standalone',
path.relative(outputFileTracingRoot, filePath)
)
)
}
await recursiveCopy(
path.join(distDir, SERVER_DIRECTORY, 'pages'),
path.join(
distDir,
'standalone',
path.relative(outputFileTracingRoot, distDir),
SERVER_DIRECTORY,
'pages'
)
)
}

staticPages.forEach((pg) => allStaticPages.add(pg))
pageInfos.forEach((info: PageInfo, key: string) => {
allPageInfos.set(key, info)
Expand Down
113 changes: 112 additions & 1 deletion packages/next/build/utils.ts
Expand Up @@ -24,7 +24,10 @@ import { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic'
import escapePathDelimiters from '../shared/lib/router/utils/escape-path-delimiters'
import { findPageFile } from '../server/lib/find-page-file'
import { GetStaticPaths, PageConfig } from 'next/types'
import { denormalizePagePath } from '../server/normalize-page-path'
import {
denormalizePagePath,
normalizePagePath,
} from '../server/normalize-page-path'
import { BuildManifest } from '../server/get-page-files'
import { removePathTrailingSlash } from '../client/normalize-trailing-slash'
import { UnwrapPromise } from '../lib/coalesced-function'
Expand All @@ -35,6 +38,8 @@ import { trace } from '../trace'
import { setHttpAgentOptions } from '../server/config'
import { NextConfigComplete } from '../server/config-shared'
import isError from '../lib/is-error'
import { recursiveDelete } from '../lib/recursive-delete'
import { Sema } from 'next/dist/compiled/async-sema'

const { builtinModules } = require('module')
const RESERVED_PAGE = /^\/(_app|_error|_document|api(\/|$))/
Expand Down Expand Up @@ -1146,6 +1151,112 @@ export function getUnresolvedModuleFromError(
return builtinModules.find((item: string) => item === moduleName)
}

export async function copyTracedFiles(
dir: string,
distDir: string,
pageKeys: string[],
tracingRoot: string,
serverConfig: { [key: string]: any }
) {
const outputPath = path.join(distDir, 'standalone')
const copiedFiles = new Set()
await recursiveDelete(outputPath)

async function handleTraceFiles(traceFilePath: string) {
const traceData = JSON.parse(await fs.readFile(traceFilePath, 'utf8')) as {
files: string[]
}
const copySema = new Sema(10, { capacity: traceData.files.length })
const traceFileDir = path.dirname(traceFilePath)

await Promise.all(
traceData.files.map(async (relativeFile) => {
await copySema.acquire()

const tracedFilePath = path.join(traceFileDir, relativeFile)
const fileOutputPath = path.join(
outputPath,
path.relative(tracingRoot, tracedFilePath)
)

if (!copiedFiles.has(fileOutputPath)) {
copiedFiles.add(fileOutputPath)

await fs.mkdir(path.dirname(fileOutputPath), { recursive: true })
const symlink = await fs.readlink(tracedFilePath).catch(() => null)

if (symlink) {
console.log('symlink', path.relative(tracingRoot, symlink))
await fs.symlink(
path.relative(tracingRoot, symlink),
fileOutputPath
)
} else {
await fs.copyFile(tracedFilePath, fileOutputPath)
}
}

await copySema.release()
})
)
}

for (const page of pageKeys) {
const pageFile = path.join(
distDir,
'server',
'pages',
`${normalizePagePath(page)}.js`
)
const pageTraceFile = `${pageFile}.nft.json`
await handleTraceFiles(pageTraceFile)
}
await handleTraceFiles(path.join(distDir, 'next-server.js.nft.json'))
const serverOutputPath = path.join(
outputPath,
path.relative(tracingRoot, dir),
'server.js'
)
await fs.writeFile(
serverOutputPath,
`
process.env.NODE_ENV = 'production'
process.chdir(__dirname)
const NextServer = require('next/dist/server/next-server').default
const http = require('http')
const path = require('path')
const nextServer = new NextServer({
dir: path.join(__dirname),
dev: false,
conf: ${JSON.stringify({
...serverConfig,
distDir: `./${path.relative(dir, distDir)}`,
})},
})
const handler = nextServer.getRequestHandler()
const server = http.createServer(async (req, res) => {
try {
await handler(req, res)
} catch (err) {
console.error(err);
res.statusCode = 500
res.end('internal server error')
}
})
const currentPort = process.env.PORT || 3000
server.listen(currentPort, (err) => {
if (err) {
console.error("Failed to start server", err)
process.exit(1)
}
console.log("Listening on port", currentPort)
})
`
)
}
export function isReservedPage(page: string) {
return RESERVED_PAGE.test(page)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/next/lib/recursive-copy.ts
Expand Up @@ -47,7 +47,7 @@ export async function recursiveCopy(

if (isDirectory) {
try {
await promises.mkdir(target)
await promises.mkdir(target, { recursive: true })
} catch (err) {
// do not throw `folder already exists` errors
if (isError(err) && err.code !== 'EEXIST') {
Expand Down
40 changes: 27 additions & 13 deletions packages/next/lib/recursive-delete.ts
@@ -1,13 +1,17 @@
import { Dirent, promises } from 'fs'
import { join } from 'path'
import { join, isAbsolute, dirname } from 'path'
import { promisify } from 'util'
import isError from './is-error'

const sleep = promisify(setTimeout)

const unlinkFile = async (p: string, t = 1): Promise<void> => {
const unlinkPath = async (p: string, isDir = false, t = 1): Promise<void> => {
try {
await promises.unlink(p)
if (isDir) {
await promises.rmdir(p)
} else {
await promises.unlink(p)
}
} catch (e) {
const code = isError(e) && e.code
if (
Expand All @@ -18,7 +22,7 @@ const unlinkFile = async (p: string, t = 1): Promise<void> => {
t < 3
) {
await sleep(t * 100)
return unlinkFile(p, t++)
return unlinkPath(p, isDir, t++)
}

if (code === 'ENOENT') {
Expand Down Expand Up @@ -58,19 +62,29 @@ export async function recursiveDelete(
// readdir does not follow symbolic links
// if part is a symbolic link, follow it using stat
let isDirectory = part.isDirectory()
if (part.isSymbolicLink()) {
const stats = await promises.stat(absolutePath)
isDirectory = stats.isDirectory()
const isSymlink = part.isSymbolicLink()

if (isSymlink) {
const linkPath = await promises.readlink(absolutePath)

try {
const stats = await promises.stat(
isAbsolute(linkPath)
? linkPath
: join(dirname(absolutePath), linkPath)
)
isDirectory = stats.isDirectory()
} catch (_) {}
}

const pp = join(previousPath, part.name)
if (isDirectory && (!exclude || !exclude.test(pp))) {
await recursiveDelete(absolutePath, exclude, pp)
return promises.rmdir(absolutePath)
}
const isNotExcluded = !exclude || !exclude.test(pp)

if (!exclude || !exclude.test(pp)) {
return unlinkFile(absolutePath)
if (isNotExcluded) {
if (isDirectory) {
await recursiveDelete(absolutePath, exclude, pp)
}
return unlinkPath(absolutePath, !isSymlink && isDirectory)
}
})
)
Expand Down
2 changes: 2 additions & 0 deletions packages/next/server/config-shared.ts
Expand Up @@ -157,6 +157,7 @@ export type NextConfig = { [key: string]: any } & {
fullySpecified?: boolean
urlImports?: NonNullable<webpack5.Configuration['experiments']>['buildHttp']
outputFileTracingRoot?: string
outputStandalone?: boolean
}
}

Expand Down Expand Up @@ -239,6 +240,7 @@ export const defaultConfig: NextConfig = {
serverComponents: false,
fullySpecified: false,
outputFileTracingRoot: process.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT || '',
outputStandalone: !!process.env.NEXT_PRIVATE_STANDALONE,
},
future: {
strictPostcssConfiguration: false,
Expand Down
12 changes: 7 additions & 5 deletions packages/next/server/next-server.ts
Expand Up @@ -2551,11 +2551,13 @@ export default class Server {
}

let nextFilesStatic: string[] = []
nextFilesStatic = !this.minimalMode
? recursiveReadDirSync(join(this.distDir, 'static')).map((f) =>
join('.', relative(this.dir, this.distDir), 'static', f)
)
: []

nextFilesStatic =
!this.minimalMode && fs.existsSync(join(this.distDir, 'static'))
? recursiveReadDirSync(join(this.distDir, 'static')).map((f) =>
join('.', relative(this.dir, this.distDir), 'static', f)
)
: []

return (this._validFilesystemPathSet = new Set<string>([
...nextFilesStatic,
Expand Down

1 comment on commit eb7b401

@ijjk
Copy link
Member Author

@ijjk ijjk commented on eb7b401 Nov 9, 2021

Choose a reason for hiding this comment

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

Stats from current release

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
buildDuration 22s 22.1s ⚠️ +119ms
buildDurationCached 4.4s 4.6s ⚠️ +208ms
nodeModulesSize 333 MB 333 MB ⚠️ +97.1 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
/ failed reqs 0 0
/ total time (seconds) 3.572 3.706 ⚠️ +0.13
/ avg req/sec 699.8 674.67 ⚠️ -25.13
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.708 1.758 ⚠️ +0.05
/error-in-render avg req/sec 1463.6 1422.38 ⚠️ -41.22
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
450.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42.2 kB 42.2 kB
main-HASH.js gzip 28 kB 28.1 kB ⚠️ +32 B
webpack-HASH.js gzip 1.45 kB 1.45 kB -1 B
Overall change 71.9 kB 71.9 kB ⚠️ +31 B
Legacy Client Bundles (polyfills)
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
_app-HASH.js gzip 1.23 kB 1.23 kB
_error-HASH.js gzip 194 B 194 B
amp-HASH.js gzip 312 B 312 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 2.38 kB 2.38 kB
head-HASH.js gzip 350 B 350 B
hooks-HASH.js gzip 635 B 635 B
image-HASH.js gzip 4.44 kB 4.44 kB
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 1.87 kB 1.87 kB
routerDirect..HASH.js gzip 321 B 321 B
script-HASH.js gzip 383 B 383 B
withRouter-HASH.js gzip 318 B 318 B
334f979574ae..6f4.css gzip 106 B 107 B ⚠️ +1 B
Overall change 13.1 kB 13.1 kB ⚠️ +1 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
_buildManifest.js gzip 459 B 460 B ⚠️ +1 B
Overall change 459 B 460 B ⚠️ +1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
index.html gzip 522 B 524 B ⚠️ +2 B
link.html gzip 535 B 536 B ⚠️ +1 B
withRouter.html gzip 515 B 517 B ⚠️ +2 B
Overall change 1.57 kB 1.58 kB ⚠️ +5 B

Diffs

Diff for _buildManifest.js
@@ -4,8 +4,8 @@ self.__BUILD_MANIFEST = {
   "/_error": ["static\u002Fchunks\u002Fpages\u002F_error-97db2c91e74bb63f.js"],
   "/amp": ["static\u002Fchunks\u002Fpages\u002Famp-8c7b17a56b7abb6e.js"],
   "/css": [
-    "static\u002Fcss\u002F7edf9ee7c3885268.css",
-    "static\u002Fchunks\u002Fpages\u002Fcss-99ad492aad2c14e4.js"
+    "static\u002Fcss\u002F94fdbc56eafa2039.css",
+    "static\u002Fchunks\u002Fpages\u002Fcss-deb2f2a41a5bf511.js"
   ],
   "/dynamic": [
     "static\u002Fchunks\u002Fpages\u002Fdynamic-0ead1841ed0002db.js"
Diff for css-HASH.js
@@ -50,7 +50,7 @@
 
     /***/ 3350: /***/ function(module) {
       // extracted by mini-css-extract-plugin
-      module.exports = { helloWorld: "css_helloWorld__2Fhmt" };
+      module.exports = { helloWorld: "css_helloWorld__qqNwY" };
 
       /***/
     }
Diff for main-HASH.js
@@ -116,7 +116,11 @@
         for (
           var i = 0, j = headCountEl.previousElementSibling;
           i < headCount;
-          i++, j = j.previousElementSibling
+          i++,
+            j =
+              (j === null || j === void 0
+                ? void 0
+                : j.previousElementSibling) || null
         ) {
           var ref;
           if (
@@ -142,7 +146,10 @@
             return true;
           });
         oldTags.forEach(function(t) {
-          return t.parentNode.removeChild(t);
+          var ref;
+          return (ref = t.parentNode) === null || ref === void 0
+            ? void 0
+            : ref.removeChild(t);
         });
         newTags.forEach(function(t) {
           return headEl.insertBefore(t, headCountEl);
@@ -527,7 +534,7 @@
         document.getElementById("__NEXT_DATA__").textContent
       );
       window.__NEXT_DATA__ = data;
-      var version = "12.0.3";
+      var version = "12.0.4-canary.3";
       exports.version = version;
       var looseToArray = function(input) {
         return [].slice.call(input);
@@ -1842,14 +1849,17 @@
       }
       function RouteAnnouncer() {
         var asPath = (0, _router).useRouter().asPath;
-        var ref = _slicedToArray(_react.default.useState(""), 2),
-          routeAnnouncement = ref[0],
-          setRouteAnnouncement = ref[1];
-        // Only announce the path change, but not for the first load because screen reader will do that automatically.
+        var ref1 = _slicedToArray(_react.default.useState(""), 2),
+          routeAnnouncement = ref1[0],
+          setRouteAnnouncement = ref1[1];
+        // Only announce the path change, but not for the first load because screen
+        // reader will do that automatically.
         var initialPathLoaded = _react.default.useRef(false);
-        // Every time the path changes, announce the route change. The announcement will be prioritized by h1, then title
-        // (from metadata), and finally if those don't exist, then the pathName that is in the URL. This methodology is
-        // inspired by Marcy Sutton's accessible client routing user testing. More information can be found here:
+        // Every time the path changes, announce the new page’s title following this
+        // priority: first the document title (from head), otherwise the first h1, or
+        // if none of these exist, then the pathname from the URL. This methodology is
+        // inspired by Marcy Sutton’s accessible client routing user testing. More
+        // information can be found here:
         // https://www.gatsbyjs.com/blog/2019-07-11-user-testing-accessible-client-routing/
         _react.default.useEffect(
           function() {
@@ -1857,20 +1867,22 @@
               initialPathLoaded.current = true;
               return;
             }
-            var newRouteAnnouncement;
-            var pageHeader = document.querySelector("h1");
-            if (pageHeader) {
-              newRouteAnnouncement =
-                pageHeader.innerText || pageHeader.textContent;
-            }
-            if (!newRouteAnnouncement) {
-              if (document.title) {
-                newRouteAnnouncement = document.title;
-              } else {
-                newRouteAnnouncement = asPath;
-              }
+            if (document.title) {
+              setRouteAnnouncement(document.title);
+            } else {
+              var pageHeader = document.querySelector("h1");
+              var ref;
+              var content =
+                (ref =
+                  pageHeader === null || pageHeader === void 0
+                    ? void 0
+                    : pageHeader.innerText) !== null && ref !== void 0
+                  ? ref
+                  : pageHeader === null || pageHeader === void 0
+                  ? void 0
+                  : pageHeader.textContent;
+              setRouteAnnouncement(content || asPath);
             }
-            setRouteAnnouncement(newRouteAnnouncement);
           },
           [asPath]
         );
Diff for webpack-HASH.js
@@ -171,7 +171,7 @@
     /******/ // This function allow to reference all chunks
     /******/ __webpack_require__.miniCssF = function(chunkId) {
       /******/ // return url for filenames based on template
-      /******/ return "static/css/" + "7edf9ee7c3885268" + ".css";
+      /******/ return "static/css/" + "94fdbc56eafa2039" + ".css";
       /******/
     };
     /******/
Diff for 7edf9ee7c3885268.css
@@ -1,4 +1,4 @@
-.css_helloWorld__2Fhmt {
+.css_helloWorld__qqNwY {
   color: green;
   background: url(/_next/static/media/nextjs.cae0b805.png);
 }
Diff for index.html
@@ -11,7 +11,7 @@
       src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"
     ></script>
     <script
-      src="/_next/static/chunks/webpack-43980cc4f59eb55b.js"
+      src="/_next/static/chunks/webpack-8244d589778df4b1.js"
       defer=""
     ></script>
     <script
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-8b1326231534a220.js"
+      src="/_next/static/chunks/main-f78d3bf7c627c9d4.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -11,7 +11,7 @@
       src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"
     ></script>
     <script
-      src="/_next/static/chunks/webpack-43980cc4f59eb55b.js"
+      src="/_next/static/chunks/webpack-8244d589778df4b1.js"
       defer=""
     ></script>
     <script
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-8b1326231534a220.js"
+      src="/_next/static/chunks/main-f78d3bf7c627c9d4.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -11,7 +11,7 @@
       src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"
     ></script>
     <script
-      src="/_next/static/chunks/webpack-43980cc4f59eb55b.js"
+      src="/_next/static/chunks/webpack-8244d589778df4b1.js"
       defer=""
     ></script>
     <script
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-8b1326231534a220.js"
+      src="/_next/static/chunks/main-f78d3bf7c627c9d4.js"
       defer=""
     ></script>
     <script

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
buildDuration 23.2s 23.2s -18ms
buildDurationCached 4.5s 4.4s -44ms
nodeModulesSize 333 MB 333 MB ⚠️ +97.1 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
/ failed reqs 0 0
/ total time (seconds) 3.54 3.543 0
/ avg req/sec 706.21 705.67 ⚠️ -0.54
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.581 1.634 ⚠️ +0.05
/error-in-render avg req/sec 1581.12 1530.03 ⚠️ -51.09
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
450.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42.3 kB 42.3 kB
main-HASH.js gzip 28.2 kB 28.2 kB ⚠️ +32 B
webpack-HASH.js gzip 1.43 kB 1.43 kB -1 B
Overall change 72.1 kB 72.1 kB ⚠️ +31 B
Legacy Client Bundles (polyfills)
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
_app-HASH.js gzip 1.22 kB 1.22 kB
_error-HASH.js gzip 180 B 180 B
amp-HASH.js gzip 305 B 305 B
css-HASH.js gzip 321 B 321 B
dynamic-HASH.js gzip 2.38 kB 2.38 kB
head-HASH.js gzip 342 B 342 B
hooks-HASH.js gzip 622 B 622 B
image-HASH.js gzip 4.46 kB 4.46 kB
index-HASH.js gzip 256 B 256 B
link-HASH.js gzip 1.91 kB 1.91 kB
routerDirect..HASH.js gzip 314 B 314 B
script-HASH.js gzip 375 B 375 B
withRouter-HASH.js gzip 309 B 309 B
334f979574ae..6f4.css gzip 106 B 107 B ⚠️ +1 B
Overall change 13.1 kB 13.1 kB ⚠️ +1 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
_buildManifest.js gzip 460 B 459 B -1 B
Overall change 460 B 459 B -1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary v12.0.3 vercel/next.js refs/heads/canary Change
index.html gzip 521 B 524 B ⚠️ +3 B
link.html gzip 534 B 536 B ⚠️ +2 B
withRouter.html gzip 515 B 517 B ⚠️ +2 B
Overall change 1.57 kB 1.58 kB ⚠️ +7 B

Diffs

Diff for _buildManifest.js
@@ -4,8 +4,8 @@ self.__BUILD_MANIFEST = {
   "/_error": ["static\u002Fchunks\u002Fpages\u002F_error-97db2c91e74bb63f.js"],
   "/amp": ["static\u002Fchunks\u002Fpages\u002Famp-8c7b17a56b7abb6e.js"],
   "/css": [
-    "static\u002Fcss\u002F7edf9ee7c3885268.css",
-    "static\u002Fchunks\u002Fpages\u002Fcss-99ad492aad2c14e4.js"
+    "static\u002Fcss\u002F94fdbc56eafa2039.css",
+    "static\u002Fchunks\u002Fpages\u002Fcss-deb2f2a41a5bf511.js"
   ],
   "/dynamic": [
     "static\u002Fchunks\u002Fpages\u002Fdynamic-0ead1841ed0002db.js"
Diff for css-HASH.js
@@ -50,7 +50,7 @@
 
     /***/ 3350: /***/ function(module) {
       // extracted by mini-css-extract-plugin
-      module.exports = { helloWorld: "css_helloWorld__2Fhmt" };
+      module.exports = { helloWorld: "css_helloWorld__qqNwY" };
 
       /***/
     }
Diff for main-HASH.js
@@ -116,7 +116,11 @@
         for (
           var i = 0, j = headCountEl.previousElementSibling;
           i < headCount;
-          i++, j = j.previousElementSibling
+          i++,
+            j =
+              (j === null || j === void 0
+                ? void 0
+                : j.previousElementSibling) || null
         ) {
           var ref;
           if (
@@ -142,7 +146,10 @@
             return true;
           });
         oldTags.forEach(function(t) {
-          return t.parentNode.removeChild(t);
+          var ref;
+          return (ref = t.parentNode) === null || ref === void 0
+            ? void 0
+            : ref.removeChild(t);
         });
         newTags.forEach(function(t) {
           return headEl.insertBefore(t, headCountEl);
@@ -527,7 +534,7 @@
         document.getElementById("__NEXT_DATA__").textContent
       );
       window.__NEXT_DATA__ = data;
-      var version = "12.0.3";
+      var version = "12.0.4-canary.3";
       exports.version = version;
       var looseToArray = function(input) {
         return [].slice.call(input);
@@ -1842,14 +1849,17 @@
       }
       function RouteAnnouncer() {
         var asPath = (0, _router).useRouter().asPath;
-        var ref = _slicedToArray(_react.default.useState(""), 2),
-          routeAnnouncement = ref[0],
-          setRouteAnnouncement = ref[1];
-        // Only announce the path change, but not for the first load because screen reader will do that automatically.
+        var ref1 = _slicedToArray(_react.default.useState(""), 2),
+          routeAnnouncement = ref1[0],
+          setRouteAnnouncement = ref1[1];
+        // Only announce the path change, but not for the first load because screen
+        // reader will do that automatically.
         var initialPathLoaded = _react.default.useRef(false);
-        // Every time the path changes, announce the route change. The announcement will be prioritized by h1, then title
-        // (from metadata), and finally if those don't exist, then the pathName that is in the URL. This methodology is
-        // inspired by Marcy Sutton's accessible client routing user testing. More information can be found here:
+        // Every time the path changes, announce the new page’s title following this
+        // priority: first the document title (from head), otherwise the first h1, or
+        // if none of these exist, then the pathname from the URL. This methodology is
+        // inspired by Marcy Sutton’s accessible client routing user testing. More
+        // information can be found here:
         // https://www.gatsbyjs.com/blog/2019-07-11-user-testing-accessible-client-routing/
         _react.default.useEffect(
           function() {
@@ -1857,20 +1867,22 @@
               initialPathLoaded.current = true;
               return;
             }
-            var newRouteAnnouncement;
-            var pageHeader = document.querySelector("h1");
-            if (pageHeader) {
-              newRouteAnnouncement =
-                pageHeader.innerText || pageHeader.textContent;
-            }
-            if (!newRouteAnnouncement) {
-              if (document.title) {
-                newRouteAnnouncement = document.title;
-              } else {
-                newRouteAnnouncement = asPath;
-              }
+            if (document.title) {
+              setRouteAnnouncement(document.title);
+            } else {
+              var pageHeader = document.querySelector("h1");
+              var ref;
+              var content =
+                (ref =
+                  pageHeader === null || pageHeader === void 0
+                    ? void 0
+                    : pageHeader.innerText) !== null && ref !== void 0
+                  ? ref
+                  : pageHeader === null || pageHeader === void 0
+                  ? void 0
+                  : pageHeader.textContent;
+              setRouteAnnouncement(content || asPath);
             }
-            setRouteAnnouncement(newRouteAnnouncement);
           },
           [asPath]
         );
Diff for webpack-HASH.js
@@ -171,7 +171,7 @@
     /******/ // This function allow to reference all chunks
     /******/ __webpack_require__.miniCssF = function(chunkId) {
       /******/ // return url for filenames based on template
-      /******/ return "static/css/" + "7edf9ee7c3885268" + ".css";
+      /******/ return "static/css/" + "94fdbc56eafa2039" + ".css";
       /******/
     };
     /******/
Diff for 7edf9ee7c3885268.css
@@ -1,4 +1,4 @@
-.css_helloWorld__2Fhmt {
+.css_helloWorld__qqNwY {
   color: green;
   background: url(/_next/static/media/nextjs.cae0b805.png);
 }
Diff for index.html
@@ -11,7 +11,7 @@
       src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"
     ></script>
     <script
-      src="/_next/static/chunks/webpack-43980cc4f59eb55b.js"
+      src="/_next/static/chunks/webpack-8244d589778df4b1.js"
       defer=""
     ></script>
     <script
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-8b1326231534a220.js"
+      src="/_next/static/chunks/main-f78d3bf7c627c9d4.js"
       defer=""
     ></script>
     <script
Diff for link.html
@@ -11,7 +11,7 @@
       src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"
     ></script>
     <script
-      src="/_next/static/chunks/webpack-43980cc4f59eb55b.js"
+      src="/_next/static/chunks/webpack-8244d589778df4b1.js"
       defer=""
     ></script>
     <script
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-8b1326231534a220.js"
+      src="/_next/static/chunks/main-f78d3bf7c627c9d4.js"
       defer=""
     ></script>
     <script
Diff for withRouter.html
@@ -11,7 +11,7 @@
       src="/_next/static/chunks/polyfills-5cd94c89d3acac5f.js"
     ></script>
     <script
-      src="/_next/static/chunks/webpack-43980cc4f59eb55b.js"
+      src="/_next/static/chunks/webpack-8244d589778df4b1.js"
       defer=""
     ></script>
     <script
@@ -19,7 +19,7 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-8b1326231534a220.js"
+      src="/_next/static/chunks/main-f78d3bf7c627c9d4.js"
       defer=""
     ></script>
     <script

Please sign in to comment.