Skip to content

Commit

Permalink
Merge branch 'i18n/stabilize-test' of github.com:ijjk/next.js into i1…
Browse files Browse the repository at this point in the history
…8n/stabilize-test
  • Loading branch information
ijjk committed Oct 16, 2020
2 parents 4951bab + d4a0d2a commit 23a1f53
Show file tree
Hide file tree
Showing 25 changed files with 246 additions and 33 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Expand Up @@ -17,5 +17,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "9.5.6-canary.3"
"version": "9.5.6-canary.4"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"description": "ESLint plugin for NextJS.",
"main": "lib/index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-google-analytics/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-google-analytics",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-google-analytics"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-sentry/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-sentry",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-sentry"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"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",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
9 changes: 9 additions & 0 deletions packages/next/build/index.ts
Expand Up @@ -1159,6 +1159,15 @@ export default async function build(
printCustomRoutes({ redirects, rewrites, headers })
}

if (config.experimental.analyticsId) {
console.log(
chalk.bold.green('Next.js Analytics') +
' is enabled for this production build. ' +
"You'll receive a Real Experience Score computed by all of your visitors."
)
console.log('')
}

if (tracer) {
const parsedResults = await tracer.profiler.stopProfiling()
await new Promise((resolve) => {
Expand Down
3 changes: 3 additions & 0 deletions packages/next/build/webpack-config.ts
Expand Up @@ -1015,6 +1015,9 @@ export default async function getBaseWebpackConfig(
'process.env.__NEXT_i18n_SUPPORT': JSON.stringify(
!!config.experimental.i18n
),
'process.env.__NEXT_ANALYTICS_ID': JSON.stringify(
config.experimental.analyticsId
),
...(isServer
? {
// Fix bad-actors in the npm ecosystem (e.g. `node-formidable`)
Expand Down
22 changes: 10 additions & 12 deletions packages/next/client/image.tsx
Expand Up @@ -16,14 +16,12 @@ type ImageData = {
breakpoints?: number[]
}

type ImageProps = {
type ImageProps = Omit<JSX.IntrinsicElements['img'], 'src' | 'sizes'> & {
src: string
host: string
sizes: string
breakpoints: number[]
priority: boolean
unoptimized: boolean
rest: any[]
host?: string
sizes?: string
priority?: boolean
unoptimized?: boolean
}

let imageData: any = process.env.__NEXT_IMAGE_OPTS
Expand Down Expand Up @@ -73,15 +71,15 @@ type PreloadData = {
src: string
host: string
widths: number[]
sizes: string
unoptimized: boolean
sizes?: string
unoptimized?: boolean
}

function generatePreload({
src,
host,
widths,
unoptimized,
unoptimized = false,
sizes,
}: PreloadData): ReactElement {
// This function generates an image preload that makes use of the "imagesrcset" and "imagesizes"
Expand All @@ -106,8 +104,8 @@ export default function Image({
src,
host,
sizes,
unoptimized,
priority,
unoptimized = false,
priority = false,
...rest
}: ImageProps) {
// Sanity Checks:
Expand Down
40 changes: 40 additions & 0 deletions packages/next/client/performance-relayer.ts
Expand Up @@ -8,13 +8,53 @@ import {
ReportHandler,
} from 'web-vitals'

const initialHref = location.href
let isRegistered = false
let userReportHandler: ReportHandler | undefined

function onReport(metric: Metric) {
if (userReportHandler) {
userReportHandler(metric)
}

// This code is not shipped, executed, or present in the client-side
// JavaScript bundle unless explicitly enabled in your application.
//
// When this feature is enabled, we'll make it very clear by printing a
// message during the build (`next build`).
if (
process.env.NODE_ENV === 'production' &&
// This field is empty unless you explicitly configure it:
process.env.__NEXT_ANALYTICS_ID
) {
const body: Record<string, string> = {
dsn: process.env.__NEXT_ANALYTICS_ID,
id: metric.id,
page: window.__NEXT_DATA__.page,
href: initialHref,
event_name: metric.name,
value: metric.value.toString(),
speed:
'connection' in navigator &&
navigator['connection'] &&
'effectiveType' in navigator['connection']
? (navigator['connection']['effectiveType'] as string)
: '',
}

const blob = new Blob([new URLSearchParams(body).toString()], {
// This content type is necessary for `sendBeacon`:
type: 'application/x-www-form-urlencoded',
})
const vitalsUrl = 'https://vitals.vercel-analytics.com/v1/vitals'
;(navigator.sendBeacon && navigator.sendBeacon(vitalsUrl, blob)) ||
fetch(vitalsUrl, {
body: blob,
method: 'POST',
credentials: 'omit',
keepalive: true,
})
}
}

export default (onPerfEntry?: ReportHandler) => {
Expand Down
1 change: 1 addition & 0 deletions packages/next/next-server/server/config.ts
Expand Up @@ -60,6 +60,7 @@ const defaultConfig: { [key: string]: any } = {
optimizeImages: false,
scrollRestoration: false,
i18n: false,
analyticsId: process.env.VERCEL_ANALYTICS_ID || '',
},
future: {
excludeDefaultMomentLocales: false,
Expand Down
12 changes: 6 additions & 6 deletions packages/next/package.json
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -79,10 +79,10 @@
"@babel/runtime": "7.11.2",
"@babel/types": "7.11.5",
"@hapi/accept": "5.0.1",
"@next/env": "9.5.6-canary.3",
"@next/polyfill-module": "9.5.6-canary.3",
"@next/react-dev-overlay": "9.5.6-canary.3",
"@next/react-refresh-utils": "9.5.6-canary.3",
"@next/env": "9.5.6-canary.4",
"@next/polyfill-module": "9.5.6-canary.4",
"@next/react-dev-overlay": "9.5.6-canary.4",
"@next/react-refresh-utils": "9.5.6-canary.4",
"ast-types": "0.13.2",
"babel-plugin-transform-define": "2.0.0",
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
Expand Down Expand Up @@ -126,7 +126,7 @@
"react-dom": "^16.6.0"
},
"devDependencies": {
"@next/polyfill-nomodule": "9.5.6-canary.3",
"@next/polyfill-nomodule": "9.5.6-canary.4",
"@taskr/clear": "1.1.0",
"@taskr/esnext": "1.1.0",
"@taskr/watch": "1.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-dev-overlay/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/react-dev-overlay",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"description": "A development-only overlay for developing React applications.",
"repository": {
"url": "vercel/next.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-refresh-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/react-refresh-utils",
"version": "9.5.6-canary.3",
"version": "9.5.6-canary.4",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
Expand Down
15 changes: 15 additions & 0 deletions test/integration/relay-analytics-disabled/pages/_app.js
@@ -0,0 +1,15 @@
/* global localStorage */
/* eslint-disable camelcase */
import App from 'next/app'

export default class MyApp extends App {}

/*
Method is experimental and will eventually be handled in a Next.js plugin
*/
export function reportWebVitals(data) {
localStorage.setItem(
data.name || data.entryType,
data.value !== undefined ? data.value : data.startTime
)
}
25 changes: 25 additions & 0 deletions test/integration/relay-analytics-disabled/pages/index.js
@@ -0,0 +1,25 @@
if (typeof navigator !== 'undefined') {
window.__BEACONS = window.__BEACONS || []

navigator.sendBeacon = async function () {
const args = await Promise.all(
[...arguments].map((v) => {
if (v instanceof Blob) {
return v.text()
}
return v
})
)

window.__BEACONS.push(args)
}
}

export default () => {
return (
<div>
<h1>Foo!</h1>
<h2>bar!</h2>
</div>
)
}
72 changes: 72 additions & 0 deletions test/integration/relay-analytics-disabled/test/index.test.js
@@ -0,0 +1,72 @@
/* eslint-env jest */

import fs from 'fs-extra'
import { findPort, killApp, nextBuild, nextStart } from 'next-test-utils'
import webdriver from 'next-webdriver'
import path, { join } from 'path'

const appDir = join(__dirname, '../')
let appPort
let server
jest.setTimeout(1000 * 60 * 2)

let buildManifest

describe('Analytics relayer (disabled)', () => {
let stdout
beforeAll(async () => {
appPort = await findPort()
;({ stdout } = await nextBuild(appDir, [], {
stdout: true,
}))
buildManifest = require(path.join(
appDir,
'.next/build-manifest.json'
), 'utf8')
server = await nextStart(appDir, appPort)
})
afterAll(() => killApp(server))

it('Does not relay any data', async () => {
const browser = await webdriver(appPort, '/')
await browser.waitForElementByCss('h1')
const h1Text = await browser.elementByCss('h1').text()
const firstContentfulPaint = parseFloat(
await browser.eval('localStorage.getItem("FCP")')
)

expect(h1Text).toMatch(/Foo!/)

expect(firstContentfulPaint).not.toBeNaN()
expect(firstContentfulPaint).toBeGreaterThan(0)

const beacons = (await browser.eval('window.__BEACONS')).map(([, value]) =>
Object.fromEntries(new URLSearchParams(value))
)

expect(beacons.length).toBe(0)

expect(stdout).not.toMatch('Next.js Analytics')

await browser.close()
})

it('Does not include the code', async () => {
const pageFiles = [
...new Set([
...buildManifest.pages['/'].filter((file) => file.endsWith('.js')),
...buildManifest.pages['/_app'].filter((file) => file.endsWith('.js')),
]),
]

expect(pageFiles.length).toBeGreaterThan(1)

for (const pageFile of pageFiles) {
const content = await fs.readFile(
path.join(appDir, '.next', pageFile),
'utf8'
)
expect(content).not.toMatch('vercel-analytics')
}
})
})

0 comments on commit 23a1f53

Please sign in to comment.