diff --git a/docs/basic-features/data-fetching.md b/docs/basic-features/data-fetching.md index cf0dbe880712e..ef4c057382cdf 100644 --- a/docs/basic-features/data-fetching.md +++ b/docs/basic-features/data-fetching.md @@ -72,7 +72,7 @@ The `context` parameter is an object containing the following keys: `getStaticProps` should return an object with: -- `props` - A **required** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) +- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) - `revalidate` - An **optional** amount in seconds after which a page re-generation can occur. More on [Incremental Static Regeneration](#incremental-static-regeneration) - `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works: @@ -672,7 +672,7 @@ The `context` parameter is an object containing the following keys: `getServerSideProps` should return an object with: -- `props` - A **required** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) +- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) - `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works: ```js diff --git a/lerna.json b/lerna.json index 4dedf0743b0d6..6c7ab55207ae1 100644 --- a/lerna.json +++ b/lerna.json @@ -17,5 +17,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "10.2.1-canary.6" + "version": "10.2.1-canary.8" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 7f6f171dd2a06..23a336493b726 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 38a607e2b025f..f067eb13682df 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "ESLint configuration used by NextJS.", "main": "index.js", "license": "MIT", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 630e17807d2df..a1b1d1a67f4ca 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "ESLint plugin for NextJS.", "main": "lib/index.js", "license": "MIT", diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 3f072b1896b6d..6eb2c8d58e002 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index b733c95cb2607..3defffc78fdcf 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "license": "MIT", "dependencies": { "chalk": "4.1.0", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index fe6f68a33d661..cfc22aae7dbff 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 727f6252ba27e..4d1b57f3da0b9 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index dcf0378fc59be..eae3025511732 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 5ce02915b9cd7..b561e0ba91e6a 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index be24455dd3410..363bba5298a8c 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next/build/babel/preset.ts b/packages/next/build/babel/preset.ts index 04a9aee246dd9..32657be2e384d 100644 --- a/packages/next/build/babel/preset.ts +++ b/packages/next/build/babel/preset.ts @@ -41,7 +41,6 @@ type NextBabelPresetOptions = { 'preset-react'?: any 'class-properties'?: any 'transform-runtime'?: any - 'experimental-modern-preset'?: PluginItem 'styled-jsx'?: StyledJsxBabelOptions 'preset-typescript'?: any } @@ -89,10 +88,6 @@ export default ( (Boolean(api.caller((caller: any) => !!caller && caller.hasJsxRuntime)) && options['preset-react']?.runtime !== 'classic') - const isLaxModern = - options['preset-env']?.targets && - options['preset-env'].targets.esmodules === true - const presetEnvConfig = { // In the test environment `modules` is often needed to be set to true, babel figures that out by itself using the `'auto'` option // In production/development this option is set to `false` so that webpack can handle import/export with tree-shaking @@ -122,17 +117,10 @@ export default ( } } - // specify a preset to use instead of @babel/preset-env - const customModernPreset = - isLaxModern && options['experimental-modern-preset'] - return { sourceType: 'unambiguous', presets: [ - customModernPreset || [ - require('next/dist/compiled/babel/preset-env'), - presetEnvConfig, - ], + [require('next/dist/compiled/babel/preset-env'), presetEnvConfig], [ require('next/dist/compiled/babel/preset-react'), { diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 89617e2e609e9..182680febcfc0 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -79,6 +79,7 @@ import { trace, setGlobal } from '../telemetry/trace' import { collectPages, detectConflictingPaths, + computeFromManifest, getJsPageSizeInKb, getNamedExports, hasCustomGetInitialProps, @@ -724,6 +725,11 @@ export default async function build( ) } + const computedManifestData = await computeFromManifest( + buildManifest, + distDir, + config.experimental.gzipSize + ) await Promise.all( pageKeys.map(async (page) => { const checkPageSpan = staticCheckSpan.traceChild('check-page', { @@ -734,7 +740,9 @@ export default async function build( const [selfSize, allSize] = await getJsPageSizeInKb( actualPage, distDir, - buildManifest + buildManifest, + config.experimental.gzipSize, + computedManifestData ) let isSsg = false @@ -1525,6 +1533,7 @@ export default async function build( useStatic404, pageExtensions: config.pageExtensions, buildManifest, + gzipSize: config.experimental.gzipSize, }) ) diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index c29735acdfb0b..14a00b71cdaa0 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -1,8 +1,9 @@ import '../next-server/server/node-polyfill-fetch' import chalk from 'chalk' -import gzipSize from 'next/dist/compiled/gzip-size' +import getGzipSize from 'next/dist/compiled/gzip-size' import textTable from 'next/dist/compiled/text-table' import path from 'path' +import { promises as fs } from 'fs' import { isValidElementType } from 'react-is' import stripAnsi from 'next/dist/compiled/strip-ansi' import { @@ -32,11 +33,20 @@ import * as Log from './output/log' import { loadComponents } from '../next-server/server/load-components' import { trace } from '../telemetry/trace' -const fileGzipStats: { [k: string]: Promise } = {} +const fileGzipStats: { [k: string]: Promise | undefined } = {} const fsStatGzip = (file: string) => { - if (fileGzipStats[file]) return fileGzipStats[file] - fileGzipStats[file] = gzipSize.file(file) - return fileGzipStats[file] + const cached = fileGzipStats[file] + if (cached) return cached + return (fileGzipStats[file] = getGzipSize.file(file)) +} + +const fileSize = async (file: string) => (await fs.stat(file)).size + +const fileStats: { [k: string]: Promise | undefined } = {} +const fsStat = (file: string) => { + const cached = fileStats[file] + if (cached) return cached + return (fileStats[file] = fileSize(file)) } export function collectPages( @@ -70,6 +80,7 @@ export async function printTreeView( pageExtensions, buildManifest, useStatic404, + gzipSize = true, }: { distPath: string buildId: string @@ -77,6 +88,7 @@ export async function printTreeView( pageExtensions: string[] buildManifest: BuildManifest useStatic404: boolean + gzipSize?: boolean } ) { const getPrettySize = (_size: number): string => { @@ -96,7 +108,7 @@ export async function printTreeView( // Re-add `static/` for root files .replace(/^/, 'static') // Remove file hash - .replace(/[.-]([0-9a-z]{6})[0-9a-z]{14}(?=\.)/, '.$1') + .replace(/(?:^|[.-])([0-9a-z]{6})[0-9a-z]{14}(?=\.)/, '.$1') const messages: [string, string, string][] = [ ['Page', 'Size', 'First Load JS'].map((entry) => @@ -115,7 +127,12 @@ export async function printTreeView( list = [...list, '/404'] } - const sizeData = await computeFromManifest(buildManifest, distPath, pageInfos) + const sizeData = await computeFromManifest( + buildManifest, + distPath, + gzipSize, + pageInfos + ) const pageList = list .slice() @@ -378,9 +395,10 @@ let cachedBuildManifest: BuildManifest | undefined let lastCompute: ComputeManifestShape | undefined let lastComputePageInfo: boolean | undefined -async function computeFromManifest( +export async function computeFromManifest( manifest: BuildManifest, distPath: string, + gzipSize: boolean = true, pageInfos?: Map ): Promise { if ( @@ -414,6 +432,8 @@ async function computeFromManifest( }) }) + const getSize = gzipSize ? fsStatGzip : fsStat + const commonFiles = [...files.entries()] .filter(([, len]) => len === expected || len === Infinity) .map(([f]) => f) @@ -426,7 +446,7 @@ async function computeFromManifest( stats = await Promise.all( commonFiles.map( async (f) => - [f, await fsStatGzip(path.join(distPath, f))] as [string, number] + [f, await getSize(path.join(distPath, f))] as [string, number] ) ) } catch (_) { @@ -438,7 +458,7 @@ async function computeFromManifest( uniqueStats = await Promise.all( uniqueFiles.map( async (f) => - [f, await fsStatGzip(path.join(distPath, f))] as [string, number] + [f, await getSize(path.join(distPath, f))] as [string, number] ) ) } catch (_) { @@ -486,9 +506,13 @@ function sum(a: number[]): number { export async function getJsPageSizeInKb( page: string, distPath: string, - buildManifest: BuildManifest + buildManifest: BuildManifest, + gzipSize: boolean = true, + computedManifestData?: ComputeManifestShape ): Promise<[number, number]> { - const data = await computeFromManifest(buildManifest, distPath) + const data = + computedManifestData || + (await computeFromManifest(buildManifest, distPath, gzipSize)) const fnFilterJs = (entry: string) => entry.endsWith('.js') @@ -507,11 +531,13 @@ export async function getJsPageSizeInKb( data.commonFiles ).map(fnMapRealPath) + const getSize = gzipSize ? fsStatGzip : fsStat + try { // Doesn't use `Promise.all`, as we'd double compute duplicate files. This // function is memoized, so the second one will instantly resolve. - const allFilesSize = sum(await Promise.all(allFilesReal.map(fsStatGzip))) - const selfFilesSize = sum(await Promise.all(selfFilesReal.map(fsStatGzip))) + const allFilesSize = sum(await Promise.all(allFilesReal.map(getSize))) + const selfFilesSize = sum(await Promise.all(selfFilesReal.map(getSize))) return [selfFilesSize, allFilesSize] } catch (_) {} diff --git a/packages/next/lib/typescript/writeConfigurationDefaults.ts b/packages/next/lib/typescript/writeConfigurationDefaults.ts index 0f8ee3ae4f049..04333a8b33eae 100644 --- a/packages/next/lib/typescript/writeConfigurationDefaults.ts +++ b/packages/next/lib/typescript/writeConfigurationDefaults.ts @@ -1,7 +1,6 @@ import { promises as fs } from 'fs' import chalk from 'chalk' import * as CommentJson from 'next/dist/compiled/comment-json' -import semver from 'next/dist/compiled/semver' import os from 'os' import { getTypeScriptConfiguration } from './getTypeScriptConfiguration' @@ -29,9 +28,6 @@ function getDesiredCompilerOptions( strict: { suggested: false }, forceConsistentCasingInFileNames: { suggested: true }, noEmit: { suggested: true }, - ...(semver.gte(ts.version, '4.3.0-beta') - ? { incremental: { suggested: true } } - : undefined), // These values are required and cannot be changed by the user // Keep this in sync with the webpack config diff --git a/packages/next/lib/verifyTypeScriptSetup.ts b/packages/next/lib/verifyTypeScriptSetup.ts index b37b26e050880..c2c36b2d0934e 100644 --- a/packages/next/lib/verifyTypeScriptSetup.ts +++ b/packages/next/lib/verifyTypeScriptSetup.ts @@ -8,7 +8,7 @@ import { CompileError } from './compile-error' import { FatalError } from './fatal-error' import { getTypeScriptIntent } from './typescript/getTypeScriptIntent' -import type { TypeCheckResult } from './typescript/runTypeCheck' +import { TypeCheckResult } from './typescript/runTypeCheck' import { writeAppTypeDeclarations } from './typescript/writeAppTypeDeclarations' import { writeConfigurationDefaults } from './typescript/writeConfigurationDefaults' diff --git a/packages/next/next-server/server/config-shared.ts b/packages/next/next-server/server/config-shared.ts index f64f09bef497d..42976289ee886 100644 --- a/packages/next/next-server/server/config-shared.ts +++ b/packages/next/next-server/server/config-shared.ts @@ -62,6 +62,7 @@ export type NextConfig = { [key: string]: any } & { reactRoot: boolean enableBlurryPlaceholder: boolean disableOptimizedLoading: boolean + gzipSize: boolean } } @@ -120,6 +121,7 @@ export const defaultConfig: NextConfig = { reactRoot: Number(process.env.NEXT_PRIVATE_REACT_ROOT) > 0, enableBlurryPlaceholder: false, disableOptimizedLoading: true, + gzipSize: true, }, future: { strictPostcssConfiguration: false, diff --git a/packages/next/next-server/server/config-utils.ts b/packages/next/next-server/server/config-utils.ts index 742b30bca485f..77f34ff05fb57 100644 --- a/packages/next/next-server/server/config-utils.ts +++ b/packages/next/next-server/server/config-utils.ts @@ -1,7 +1,7 @@ import path from 'path' import { Worker } from 'jest-worker' import * as Log from '../../build/output/log' -import type { CheckReasons, CheckResult } from './config-utils-worker' +import { CheckReasons, CheckResult } from './config-utils-worker' import { install, shouldLoadWithWebpack5 } from './config-utils-worker' export { install, shouldLoadWithWebpack5 } diff --git a/packages/next/next-server/server/config.ts b/packages/next/next-server/server/config.ts index 04b5691d5b0ab..beeb39de5a9fc 100644 --- a/packages/next/next-server/server/config.ts +++ b/packages/next/next-server/server/config.ts @@ -56,7 +56,11 @@ function assignDefaults(userConfig: { [key: string]: any }) { return currentConfig } - if (key === 'experimental' && value && value !== defaultConfig[key]) { + if ( + key === 'experimental' && + value !== undefined && + value !== defaultConfig[key] + ) { experimentalWarning() } diff --git a/packages/next/package.json b/packages/next/package.json index 54187910c69f4..312742c1d15aa 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -64,10 +64,10 @@ "dependencies": { "@babel/runtime": "7.12.5", "@hapi/accept": "5.0.1", - "@next/env": "10.2.1-canary.6", - "@next/polyfill-module": "10.2.1-canary.6", - "@next/react-dev-overlay": "10.2.1-canary.6", - "@next/react-refresh-utils": "10.2.1-canary.6", + "@next/env": "10.2.1-canary.8", + "@next/polyfill-module": "10.2.1-canary.8", + "@next/react-dev-overlay": "10.2.1-canary.8", + "@next/react-refresh-utils": "10.2.1-canary.8", "@opentelemetry/api": "0.14.0", "assert": "2.0.0", "ast-types": "0.13.2", @@ -151,7 +151,7 @@ "@babel/preset-typescript": "7.12.7", "@babel/traverse": "^7.12.10", "@babel/types": "7.12.12", - "@next/polyfill-nomodule": "10.2.1-canary.6", + "@next/polyfill-nomodule": "10.2.1-canary.8", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", "@taskr/watch": "1.1.0", diff --git a/packages/next/server/next.ts b/packages/next/server/next.ts index 6fd8c0e17ca21..6af1dfe57bcc1 100644 --- a/packages/next/server/next.ts +++ b/packages/next/server/next.ts @@ -1,5 +1,5 @@ import '../next-server/server/node-polyfill-fetch' -import type { +import { default as Server, ServerConstructor, } from '../next-server/server/next-server' diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 4e3185348a278..9fa4c9f309d3c 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index d13974e671051..65517d4dc8913 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "10.2.1-canary.6", + "version": "10.2.1-canary.8", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/test/integration/build-output/test/index.test.js b/test/integration/build-output/test/index.test.js index 9e2064a1c708d..7390a2dc4bcb7 100644 --- a/test/integration/build-output/test/index.test.js +++ b/test/integration/build-output/test/index.test.js @@ -2,7 +2,7 @@ import 'flat-map-polyfill' import { remove } from 'fs-extra' -import { nextBuild } from 'next-test-utils' +import { nextBuild, File } from 'next-test-utils' import { join } from 'path' import { recursiveReadDir } from 'next/dist/lib/recursive-readdir' @@ -10,133 +10,162 @@ jest.setTimeout(1000 * 60 * 2) const fixturesDir = join(__dirname, '..', 'fixtures') -describe('Build Output', () => { - describe('Basic Application Output', () => { - let stdout - const appDir = join(fixturesDir, 'basic-app') - - beforeAll(async () => { - await remove(join(appDir, '.next')) - }) +const nextConfig = new File(join(fixturesDir, 'basic-app/next.config.js')) - it('should not include internal pages', async () => { - ;({ stdout } = await nextBuild(appDir, [], { - stdout: true, - })) - - expect(stdout).toMatch(/\/ [ ]* \d{1,} B/) - expect(stdout).toMatch(/\+ First Load JS shared by all [ 0-9.]* kB/) - expect(stdout).toMatch(/ chunks\/main\.[0-9a-z]{6}\.js [ 0-9.]* kB/) - expect(stdout).toMatch(/ chunks\/framework\.[0-9a-z]{6}\.js [ 0-9. ]* kB/) - - expect(stdout).not.toContain(' /_document') - expect(stdout).not.toContain(' /_app') - expect(stdout).not.toContain(' /_error') - expect(stdout).not.toContain('') - - expect(stdout).toContain('○ /') - }) - - it('should not deviate from snapshot', async () => { - console.log(stdout) - - if (process.env.NEXT_PRIVATE_SKIP_SIZE_TESTS) { - return - } +describe('Build Output', () => { + for (const gzipSize of [true, false, undefined]) { + describe( + 'Basic Application Output' + + (gzipSize !== undefined + ? ` (with experimental.gzipSize: ${gzipSize})` + : ''), + () => { + let stdout + const appDir = join(fixturesDir, 'basic-app') + + beforeAll(async () => { + await remove(join(appDir, '.next')) + if (gzipSize !== undefined) { + nextConfig.write( + `module.exports = { experimental: { gzipSize: ${gzipSize} } };` + ) + } + }) + + if (gzipSize !== undefined) { + afterAll(async () => { + nextConfig.delete() + }) + } - const parsePageSize = (page) => - stdout.match( - new RegExp(` ${page} .*?((?:\\d|\\.){1,} (?:\\w{1,})) `) - )[1] + it('should not include internal pages', async () => { + ;({ stdout } = await nextBuild(appDir, [], { + stdout: true, + })) - const parsePageFirstLoad = (page) => - stdout.match( - new RegExp( - ` ${page} .*?(?:(?:\\d|\\.){1,}) .*? ((?:\\d|\\.){1,} (?:\\w{1,}))` + expect(stdout).toMatch(/\/ [ ]* \d{1,} B/) + expect(stdout).toMatch(/\+ First Load JS shared by all [ 0-9.]* kB/) + expect(stdout).toMatch(/ chunks\/main\.[0-9a-z]{6}\.js [ 0-9.]* kB/) + expect(stdout).toMatch( + / chunks\/framework\.[0-9a-z]{6}\.js [ 0-9. ]* kB/ ) - )[1] - const parseSharedSize = (sharedPartName) => { - const matches = stdout.match( - new RegExp(`${sharedPartName} .*? ((?:\\d|\\.){1,} (?:\\w{1,}))`) - ) + expect(stdout).not.toContain(' /_document') + expect(stdout).not.toContain(' /_app') + expect(stdout).not.toContain(' /_error') + expect(stdout).not.toContain('') + + expect(stdout).toContain('○ /') + }) + + it('should not deviate from snapshot', async () => { + console.log(stdout) + + if (process.env.NEXT_PRIVATE_SKIP_SIZE_TESTS) { + return + } + + const parsePageSize = (page) => + stdout.match( + new RegExp(` ${page} .*?((?:\\d|\\.){1,} (?:\\w{1,})) `) + )[1] + + const parsePageFirstLoad = (page) => + stdout.match( + new RegExp( + ` ${page} .*?(?:(?:\\d|\\.){1,}) .*? ((?:\\d|\\.){1,} (?:\\w{1,}))` + ) + )[1] + + const parseSharedSize = (sharedPartName) => { + const matches = stdout.match( + new RegExp(`${sharedPartName} .*? ((?:\\d|\\.){1,} (?:\\w{1,}))`) + ) + + if (!matches) { + throw new Error(`Could not match ${sharedPartName}`) + } + + return matches[1] + } + + const indexSize = parsePageSize('/') + const indexFirstLoad = parsePageFirstLoad('/') + + const err404Size = parsePageSize('/404') + const err404FirstLoad = parsePageFirstLoad('/404') + + const sharedByAll = parseSharedSize('shared by all') + const _appSize = parseSharedSize('_app\\..*?\\.js') + const webpackSize = parseSharedSize('webpack\\..*?\\.js') + const mainSize = parseSharedSize('main\\..*?\\.js') + const frameworkSize = parseSharedSize('framework\\..*?\\.js') + + for (const size of [ + indexSize, + indexFirstLoad, + err404Size, + err404FirstLoad, + sharedByAll, + _appSize, + webpackSize, + mainSize, + frameworkSize, + ]) { + expect(parseFloat(size)).toBeGreaterThan(0) + } + + const gz = gzipSize !== false + + expect(parseFloat(indexSize) / 1000).toBeCloseTo( + gz ? 0.251 : 0.394, + 2 + ) + expect(indexSize.endsWith('B')).toBe(true) - if (!matches) { - throw new Error(`Could not match ${sharedPartName}`) - } + expect(parseFloat(indexFirstLoad)).toBeCloseTo(gz ? 63.6 : 195, 1) + expect(indexFirstLoad.endsWith('kB')).toBe(true) - return matches[1] - } + expect(parseFloat(err404Size)).toBeCloseTo(gz ? 3.06 : 8.15, 1) + expect(err404Size.endsWith('kB')).toBe(true) - const indexSize = parsePageSize('/') - const indexFirstLoad = parsePageFirstLoad('/') - - const err404Size = parsePageSize('/404') - const err404FirstLoad = parsePageFirstLoad('/404') - - const sharedByAll = parseSharedSize('shared by all') - const _appSize = parseSharedSize('_app\\..*?\\.js') - const webpackSize = parseSharedSize('webpack\\..*?\\.js') - const mainSize = parseSharedSize('main\\..*?\\.js') - const frameworkSize = parseSharedSize('framework\\..*?\\.js') - - for (const size of [ - indexSize, - indexFirstLoad, - err404Size, - err404FirstLoad, - sharedByAll, - _appSize, - webpackSize, - mainSize, - frameworkSize, - ]) { - expect(parseFloat(size)).toBeGreaterThan(0) - } + expect(parseFloat(err404FirstLoad)).toBeCloseTo(gz ? 66.5 : 203, 1) + expect(err404FirstLoad.endsWith('kB')).toBe(true) - // should be no bigger than 291 bytes - expect(parseFloat(indexSize) - 291).toBeLessThanOrEqual(0) - expect(indexSize.endsWith('B')).toBe(true) + expect(parseFloat(sharedByAll)).toBeCloseTo(gz ? 63.4 : 195, 1) + expect(sharedByAll.endsWith('kB')).toBe(true) - // should be no bigger than 64.8 kb - expect(parseFloat(indexFirstLoad)).toBeCloseTo(63.6, 1) - expect(indexFirstLoad.endsWith('kB')).toBe(true) + const appSizeValue = _appSize.endsWith('kB') + ? parseFloat(_appSize) + : parseFloat(_appSize) / 1000 + expect(appSizeValue).toBeCloseTo(gz ? 1.0 : 2.18, 1) + expect(_appSize.endsWith('kB') || _appSize.endsWith(' B')).toBe(true) - expect(parseFloat(err404Size)).toBeCloseTo(3.04, 1) - expect(err404Size.endsWith('kB')).toBe(true) + const webpackSizeValue = webpackSize.endsWith('kB') + ? parseFloat(webpackSize) + : parseFloat(webpackSize) / 1000 + expect(webpackSizeValue).toBeCloseTo(gz ? 0.95 : 1.81, 2) + expect(webpackSize.endsWith('kB') || webpackSize.endsWith(' B')).toBe( + true + ) - expect(parseFloat(err404FirstLoad)).toBeCloseTo(66.3, 0) - expect(err404FirstLoad.endsWith('kB')).toBe(true) + expect(parseFloat(mainSize)).toBeCloseTo(gz ? 19.4 : 60.4, 1) + expect(mainSize.endsWith('kB')).toBe(true) - expect(parseFloat(sharedByAll)).toBeCloseTo(63.4, 1) - expect(sharedByAll.endsWith('kB')).toBe(true) + expect(parseFloat(frameworkSize)).toBeCloseTo(gz ? 42.0 : 130, 1) + expect(frameworkSize.endsWith('kB')).toBe(true) + }) - if (_appSize.endsWith('kB')) { - expect(parseFloat(_appSize)).toBeLessThanOrEqual(1.02) - expect(_appSize.endsWith('kB')).toBe(true) - } else { - expect(parseFloat(_appSize) - 1000).toBeLessThanOrEqual(0) - expect(_appSize.endsWith(' B')).toBe(true) + it('should not emit extracted comments', async () => { + const files = await recursiveReadDir( + join(appDir, '.next'), + /\.txt|\.LICENSE\./ + ) + expect(files).toEqual([]) + }) } - - expect(parseFloat(webpackSize) - 952).toBeLessThanOrEqual(0) - expect(webpackSize.endsWith(' B')).toBe(true) - - expect(parseFloat(mainSize) - 19.4).toBeLessThanOrEqual(0) - expect(mainSize.endsWith('kB')).toBe(true) - - expect(parseFloat(frameworkSize) - 42.1).toBeLessThanOrEqual(0) - expect(frameworkSize.endsWith('kB')).toBe(true) - }) - - it('should not emit extracted comments', async () => { - const files = await recursiveReadDir( - join(appDir, '.next'), - /\.txt|\.LICENSE\./ - ) - expect(files).toEqual([]) - }) - }) + ) + } describe('Custom App Output', () => { const appDir = join(fixturesDir, 'with-app') diff --git a/test/integration/tsconfig-verifier/test/index.test.js b/test/integration/tsconfig-verifier/test/index.test.js index 1011996308a4c..d5762e6ecaf52 100644 --- a/test/integration/tsconfig-verifier/test/index.test.js +++ b/test/integration/tsconfig-verifier/test/index.test.js @@ -39,7 +39,6 @@ describe('tsconfig.json verifier', () => { \\"strict\\": false, \\"forceConsistentCasingInFileNames\\": true, \\"noEmit\\": true, - \\"incremental\\": true, \\"esModuleInterop\\": true, \\"module\\": \\"esnext\\", \\"moduleResolution\\": \\"node\\", @@ -84,7 +83,6 @@ describe('tsconfig.json verifier', () => { \\"strict\\": false, \\"forceConsistentCasingInFileNames\\": true, \\"noEmit\\": true, - \\"incremental\\": true, \\"esModuleInterop\\": true, \\"module\\": \\"esnext\\", \\"moduleResolution\\": \\"node\\", @@ -152,7 +150,6 @@ describe('tsconfig.json verifier', () => { \\"strict\\": false, \\"forceConsistentCasingInFileNames\\": true, \\"noEmit\\": true, - \\"incremental\\": true, \\"moduleResolution\\": \\"node\\", \\"resolveJsonModule\\": true, \\"isolatedModules\\": true, @@ -201,7 +198,6 @@ describe('tsconfig.json verifier', () => { \\"strict\\": false, \\"forceConsistentCasingInFileNames\\": true, \\"noEmit\\": true, - \\"incremental\\": true, \\"moduleResolution\\": \\"node\\", \\"resolveJsonModule\\": true, \\"isolatedModules\\": true, @@ -247,7 +243,6 @@ describe('tsconfig.json verifier', () => { \\"strict\\": false, \\"forceConsistentCasingInFileNames\\": true, \\"noEmit\\": true, - \\"incremental\\": true, \\"moduleResolution\\": \\"node\\", \\"resolveJsonModule\\": true, \\"isolatedModules\\": true, @@ -286,7 +281,6 @@ describe('tsconfig.json verifier', () => { "strict": false, "forceConsistentCasingInFileNames": true, "noEmit": true, - "incremental": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", diff --git a/test/unit/next-babel.unit.test.js b/test/unit/next-babel.unit.test.js index ad6d2d4c5cd77..6720603350457 100644 --- a/test/unit/next-babel.unit.test.js +++ b/test/unit/next-babel.unit.test.js @@ -165,28 +165,6 @@ describe('next/babel', () => { }) }) - describe('experimental-modern-preset', () => { - it('should allow passing a custom Babel preset', () => { - const code = trim` - const [, b, c] = [...[1,2,3]]; - ({a}) => a; - ` - const output = babel(code, true, { - 'preset-env': { - targets: { - esmodules: true, - }, - }, - // our modern preset is no preset at all - 'experimental-modern-preset': () => ({}), - }) - - expect(output).toMatch(trim` - const[,b,c]=[...[1,2,3]];({a})=>a; - `) - }) - }) - describe('respect preset-react runtime', () => { it('should allow forcing on automatic mode', () => { const code = trim`const a = ()=>home`