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

Make traces in development reliable #28990

Merged
merged 20 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
719810c
Move trace directory
timneutkens Sep 10, 2021
7753757
Remove unused function
timneutkens Sep 10, 2021
23bab83
Make console trace reporter more useful
timneutkens Sep 10, 2021
d21ab1b
Ensure hot-reloader span is sent as it's the first in the dev trace
timneutkens Sep 10, 2021
3936b81
Pass span to next-export to ensure it has a parentSpan
timneutkens Sep 10, 2021
0783c8a
Ensure hooks that do not have a parent are added as a child of runWeb…
timneutkens Sep 10, 2021
c0b6ca9
Leverage traceChild instead of manually passing ids for css minimizer
timneutkens Sep 10, 2021
95ce162
Move bench directory
timneutkens Sep 10, 2021
5038ab4
Ensure webpack spans have correct parent
timneutkens Sep 11, 2021
5324463
Add nested-deps to bench directory
timneutkens Sep 12, 2021
4b2b3c0
Add name to webpack-close
timneutkens Sep 12, 2021
77df4fd
Ensure traces are flushed after each compile in development
timneutkens Sep 12, 2021
21122f9
Add trigger attribute for invalidation
timneutkens Sep 12, 2021
b105b7d
Merge branch 'canary' of github.com:vercel/next.js into add/move-trac…
timneutkens Sep 12, 2021
bf6a462
Merge branch 'canary' into add/move-trace-dir
timneutkens Sep 12, 2021
8b57283
Merge branch 'add/move-trace-dir' of github.com:timneutkens/next.js i…
timneutkens Sep 12, 2021
130bc1b
Fix linting
timneutkens Sep 12, 2021
e712f90
Add import
timneutkens Sep 13, 2021
c6b6b33
Remove unused variable
timneutkens Sep 13, 2021
652043e
Update bench/nested-deps/fuzzponent.js
timneutkens Sep 13, 2021
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
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,5 @@ packages/create-next-app/templates/**
test/integration/eslint/**
test-timings.json
packages/next/build/swc/tests/fixture/**
bench/nested-deps/pages/**
bench/nested-deps/components/**
66 changes: 0 additions & 66 deletions bench/capture-trace.js

This file was deleted.

1 change: 1 addition & 0 deletions bench/nested-deps/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
components/*
182 changes: 182 additions & 0 deletions bench/nested-deps/fuzzponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env node
const path = require('path')
const fs = require('fs')

const getSequenceGenerator = require('random-seed')
const generate = require('@babel/generator').default
const t = require('@babel/types')

const MIN_COMPONENT_NAME_LEN = 18
const MAX_COMPONENT_NAME_LEN = 24
const MIN_CHILDREN = 4
const MAX_CHILDREN = 80

const arrayUntil = (len) => [...Array(len)].map((_, i) => i)

const generateFunctionalComponentModule = (componentName, children = []) => {
const body = [
generateImport('React', 'react'),
...children.map((childName) => generateImport(childName, `./${childName}`)),
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier(componentName),
t.arrowFunctionExpression(
[],
t.parenthesizedExpression(
generateJSXElement(
'div',
children.map((childName) => generateJSXElement(childName))
)
)
)
),
]),
t.exportDefaultDeclaration(t.identifier(componentName)),
]

return t.program(body, [], 'module')
}

const generateJSXElement = (componentName, children = null) =>
t.JSXElement(
t.JSXOpeningElement(t.JSXIdentifier(componentName), [], !children),
children ? t.JSXClosingElement(t.JSXIdentifier(componentName)) : null,
children || [],
!children
)

const generateImport = (componentName, requireString) =>
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier(componentName))],
t.stringLiteral(requireString)
)

const validFirstChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const validOtherChars = validFirstChars.toLowerCase()
function generateComponentName(seqGenerator, opts) {
const numOtherChars = seqGenerator.intBetween(opts.minLen, opts.maxLen)
const firstChar = validFirstChars[seqGenerator.range(validFirstChars.length)]
const otherChars = arrayUntil(numOtherChars).map(
() => validOtherChars[seqGenerator.range(validOtherChars.length)]
)
return `${firstChar}${otherChars.join('')}`
}

function* generateModules(name, remainingDepth, seqGenerator, opts) {
const filename = `${name}.${opts.extension}`
let ast

if (name === 'index') {
name = 'RootComponent'
}

if (remainingDepth === 0) {
ast = generateFunctionalComponentModule(name)
} else {
const numChildren = seqGenerator.intBetween(opts.minChild, opts.maxChild)
const children = arrayUntil(numChildren).map(() =>
generateComponentName(seqGenerator, opts)
)
ast = generateFunctionalComponentModule(name, children)

for (const child of children) {
yield* generateModules(child, remainingDepth - 1, seqGenerator, opts)
}
}

yield {
filename,
content: generate(ast).code,
}
}

function generateFuzzponents(outdir, seed, depth, opts) {
const seqGenerator = getSequenceGenerator(seed)

const filenames = new Set()
for (const { filename, content } of generateModules(
'index',
depth,
seqGenerator,
opts
)) {
if (filenames.has(filename)) {
throw new Error(
`Seed "${seed}" generates output with filename collisions.`
)
} else {
filenames.add(filename)
}
const fpath = path.join(outdir, filename)
fs.writeFileSync(fpath, `// ${filename}\n\n${content}`)
}
}

if (require.main === module) {
const { outdir, seed, depth, ...opts } = require('yargs')
.option('depth', {
alias: 'd',
demandOption: true,
describe: 'component hierarchy depth',
type: 'number',
})
.option('seed', {
alias: 's',
demandOption: true,
describe: 'prng seed',
type: 'number',
})
.option('outdir', {
alias: 'o',
demandOption: false,
default: process.cwd(),
describe: 'the directory where components should be written',
type: 'string',
normalize: true,
})
.option('minLen', {
demandOption: false,
default: MIN_COMPONENT_NAME_LEN,
describe: 'the smallest acceptible component name length',
type: 'number',
})
.option('maxLen', {
demandOption: false,
default: MAX_COMPONENT_NAME_LEN,
describe: 'the largest acceptible component name length',
type: 'number',
})
.option('minLen', {
demandOption: false,
default: MIN_COMPONENT_NAME_LEN,
describe: 'the smallest acceptible component name length',
type: 'number',
})
.option('maxLen', {
demandOption: false,
default: MAX_COMPONENT_NAME_LEN,
describe: 'the largest acceptible component name length',
type: 'number',
})
.option('minChild', {
demandOption: false,
default: MIN_CHILDREN,
describe: 'the smallest number of acceptible component children',
type: 'number',
})
.option('maxChild', {
demandOption: false,
default: MAX_CHILDREN,
describe: 'the largest number of acceptible component children',
type: 'number',
})
.option('extension', {
default: 'jsx',
describe: 'extension to use for generated components',
type: 'string',
}).argv

generateFuzzponents(outdir, seed, depth, opts)
}

module.exports = generateFuzzponents
9 changes: 9 additions & 0 deletions bench/nested-deps/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module.exports = {
eslint: {
ignoreDuringBuilds: true,
},
experimental: {
swcLoader: true,
swcMinify: true,
},
}
10 changes: 10 additions & 0 deletions bench/nested-deps/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"prepare": "rm -rf components && node ./fuzzponent.js -d 2 -s 206 -o components",
"dev": "../../node_modules/.bin/next dev",
"build": "../../node_modules/.bin/next build",
"start": "../../node_modules/.bin/next start",
"dev-nocache": "rm -rf .next && yarn dev",
"build-nocache": "rm -rf .next && yarn build"
}
}
5 changes: 5 additions & 0 deletions bench/nested-deps/pages/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Comp from '../components/index.jsx'

export default function Home() {
return <Comp />
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@fullhuman/postcss-purgecss": "1.3.0",
"@mdx-js/loader": "0.18.0",
"@svgr/webpack": "5.5.0",
"@swc/cli": "0.1.49",
timneutkens marked this conversation as resolved.
Show resolved Hide resolved
"@swc/core": "1.2.85",
"@swc/jest": "0.2.2",
"@testing-library/react": "11.2.5",
Expand Down Expand Up @@ -117,6 +118,7 @@
"prettier": "2.3.2",
"pretty-bytes": "5.3.0",
"pretty-ms": "7.0.0",
"random-seed": "0.3.0",
"react": "17.0.2",
"react-18": "npm:react@next",
"react-dom": "17.0.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/babel/loader/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getOptions } from 'next/dist/compiled/loader-utils'
import { Span } from '../../../telemetry/trace'
import { Span } from '../../../trace'
import transform from './transform'
import { NextJsLoaderContext } from './types'

Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/babel/loader/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import PluginPass from 'next/dist/compiled/babel/core-lib-plugin-pass'

import getConfig from './get-config'
import { consumeIterator } from './util'
import { Span } from '../../../telemetry/trace'
import { Span } from '../../../trace'
import { NextJsLoaderContext } from './types'

function getTraversalParams(file: any, pluginPairs: any[]) {
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/babel/loader/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { loader } from 'next/dist/compiled/webpack/webpack'
import { Span } from '../../../telemetry/trace'
import { Span } from '../../../trace'

export interface NextJsLoaderContext extends loader.LoaderContext {
currentTraceSpan: Span
Expand Down
6 changes: 4 additions & 2 deletions packages/next/build/compiler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { webpack } from 'next/dist/compiled/webpack/webpack'
import { Span } from '../telemetry/trace'
import { Span } from '../trace'

export type CompilerResult = {
errors: string[]
Expand Down Expand Up @@ -42,7 +42,9 @@ export function runCompiler(
return new Promise((resolve, reject) => {
const compiler = webpack(config)
compiler.run((err: Error, stats: webpack.Stats) => {
const webpackCloseSpan = runWebpackSpan.traceChild('webpack-close')
const webpackCloseSpan = runWebpackSpan.traceChild('webpack-close', {
name: config.name,
})
webpackCloseSpan
.traceAsyncFn(() => closeCompiler(compiler))
.then(() => {
Expand Down
4 changes: 2 additions & 2 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import { generateBuildId } from './generate-build-id'
import { isWriteable } from './is-writeable'
import * as Log from './output/log'
import createSpinner from './spinner'
import { trace, flushAllTraces, setGlobal } from '../telemetry/trace'
import { trace, flushAllTraces, setGlobal } from '../trace'
import {
collectPages,
detectConflictingPaths,
Expand Down Expand Up @@ -1291,7 +1291,7 @@ export default async function build(
},
}

await exportApp(dir, exportOptions, exportConfig)
await exportApp(dir, exportOptions, nextBuildSpan, exportConfig)

const postBuildSpinner = createSpinner({
prefixText: `${Log.prefixes.info} Finalizing page optimization`,
Expand Down
5 changes: 5 additions & 0 deletions packages/next/build/output/log.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const prefixes = {
ready: chalk.green('ready') + ' -',
info: chalk.cyan('info') + ' -',
event: chalk.magenta('event') + ' -',
trace: chalk.magenta('trace') + ' -',
}

export function wait(...message: string[]) {
Expand All @@ -32,3 +33,7 @@ export function info(...message: string[]) {
export function event(...message: string[]) {
console.log(prefixes.event, ...message)
}

export function trace(...message: string[]) {
console.log(prefixes.trace, ...message)
}
3 changes: 3 additions & 0 deletions packages/next/build/output/store.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import createStore from 'next/dist/compiled/unistore'
import stripAnsi from 'next/dist/compiled/strip-ansi'
import { flushAllTraces } from '../../trace'

import * as Log from './log'

Expand Down Expand Up @@ -88,4 +89,6 @@ store.subscribe((state) => {
}

Log.event('compiled successfully')
// Ensure traces are flushed after each compile in development mode
flushAllTraces()
})
2 changes: 1 addition & 1 deletion packages/next/build/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { UnwrapPromise } from '../lib/coalesced-function'
import { normalizeLocalePath } from '../shared/lib/i18n/normalize-locale-path'
import * as Log from './output/log'
import { loadComponents } from '../server/load-components'
import { trace } from '../telemetry/trace'
import { trace } from '../trace'
import { setHttpAgentOptions } from '../server/config'
import { NextConfigComplete } from '../server/config-shared'

Expand Down
Loading