Skip to content

Commit

Permalink
Merge branch 'canary' into alex-language
Browse files Browse the repository at this point in the history
  • Loading branch information
petermekhaeil authored Jun 11, 2021
2 parents 484911e + fb99028 commit 8854ddd
Show file tree
Hide file tree
Showing 30 changed files with 208 additions and 85 deletions.
8 changes: 8 additions & 0 deletions docs/advanced-features/codemods.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ Codemods are transformations that run on your codebase programmatically. This al
- `--dry` Do a dry-run, no code will be edited
- `--print` Prints the changed output for comparison

## Next.js 11

### `cra-to-next` (experimental)

Migrates a Create React App project to Next.js; creating a pages directory and necessary config to match behavior. Client-side only rendering is leveraged initially to prevent breaking compatibility due to `window` usage during SSR and can be enabled seamlessly to allow gradual adoption of Next.js specific features.

Please share any feedback related to this transform [in this discussion](https://github.com/vercel/next.js/discussions/25858).

## Next.js 10

### `add-missing-react-import`
Expand Down
15 changes: 15 additions & 0 deletions errors/placeholder-blur-data-url.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# `placeholder=blur` without `blurDataURL`

#### Why This Error Occurred

You are attempting use the `next/image` component with `placeholder=blur` property but no `blurDataURL` property.

The `blurDataURL` might be missing because your using a string for `src` instead of a static import.

Or `blurDataURL` might be missing because the static import is an unsupported image format. Only jpg, png, and webp are supported at this time.

#### Possible Ways to Fix It

- Add a [`blurDataURL`](https://nextjs.org/docs/api-reference/next/image#blurdataurl) property, the contents should be a small Data URL to represent the image
- Change the [`src`](https://nextjs.org/docs/api-reference/next/image#src) property to a static import with one of the supported file types: jpg, png, or webp
- Remove the [`placeholder`](https://nextjs.org/docs/api-reference/next/image#placeholder) property, effectively no blur effect
6 changes: 6 additions & 0 deletions examples/with-redux-persist/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ This example shows how to integrate Redux with the power of Redux Persist in Nex

With the advantage of having a global state for your app using `redux`. You'll also require some of your state values to be available offline. There comes `redux-persist` using which you can persist your states in browser's local storage. While there are various ways of persisting your states which you can always find in there [documentation](https://github.com/rt2zz/redux-persist/blob/master/README.md). This is an example of how you can integrate `redux-persist` with redux along with Next.js's universal rendering approach.

## Preview

Preview the example live on [StackBlitz](http://stackblitz.com/):

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-redux-persist)

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
Expand Down
6 changes: 6 additions & 0 deletions examples/with-urql/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Use [urql](https://github.com/FormidableLabs/urql) with Next.js using SSG.

## Preview

Preview the example live on [StackBlitz](http://stackblitz.com/):

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-urql)

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
Expand Down
2 changes: 1 addition & 1 deletion examples/with-urql/graphql/client.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createClient } from 'urql'

export const client = createClient({
url: 'https://graphql-pokemon.vercel.app/',
url: 'https://graphql-pokemon2.vercel.app/',
})
6 changes: 6 additions & 0 deletions examples/with-videojs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This example shows how to use Next.js along with [Video.js](https://videojs.com) including handling of default styles.

## Preview

Preview the example live on [StackBlitz](http://stackblitz.com/):

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-videojs)

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "10.2.4-canary.12"
"version": "10.2.4-canary.13"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"description": "ESLint configuration used by NextJS.",
"main": "index.js",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
"directory": "packages/eslint-config-next"
},
"dependencies": {
"@next/eslint-plugin-next": "10.2.4-canary.12",
"@next/eslint-plugin-next": "10.2.4-canary.13",
"@rushstack/eslint-patch": "^1.0.6",
"@typescript-eslint/parser": "^4.20.0",
"eslint-import-resolver-node": "^0.3.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
20 changes: 11 additions & 9 deletions packages/next/build/webpack/loaders/next-image-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import loaderUtils from 'next/dist/compiled/loader-utils'
import sizeOf from 'image-size'
import { processBuffer } from '../../../next-server/server/lib/squoosh/main'

const PLACEHOLDER_SIZE = 8
const BLUR_IMG_SIZE = 8
const BLUR_QUALITY = 70
const VALID_BLUR_EXT = ['jpeg', 'png', 'webp']

async function nextImageLoader(content) {
const context = this.rootContext
Expand All @@ -19,20 +21,20 @@ async function nextImageLoader(content) {
}

const imageSize = sizeOf(content)
let placeholder
if (extension === 'jpeg' || extension === 'png') {
// Shrink the image's largest dimension to 6 pixels
let blurDataURL
if (VALID_BLUR_EXT.includes(extension)) {
// Shrink the image's largest dimension
const resizeOperationOpts =
imageSize.width >= imageSize.height
? { type: 'resize', width: PLACEHOLDER_SIZE }
: { type: 'resize', height: PLACEHOLDER_SIZE }
? { type: 'resize', width: BLUR_IMG_SIZE }
: { type: 'resize', height: BLUR_IMG_SIZE }
const resizedImage = await processBuffer(
content,
[resizeOperationOpts],
extension,
70
BLUR_QUALITY
)
placeholder = `data:image/${extension};base64,${resizedImage.toString(
blurDataURL = `data:image/${extension};base64,${resizedImage.toString(
'base64'
)}`
}
Expand All @@ -41,7 +43,7 @@ async function nextImageLoader(content) {
src: '/_next' + interpolatedName,
height: imageSize.height,
width: imageSize.width,
placeholder,
blurDataURL,
})

this.emitFile(interpolatedName, content, null)
Expand Down
75 changes: 43 additions & 32 deletions packages/next/client/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ interface StaticImageData {
src: string
height: number
width: number
placeholder?: string
blurDataURL?: string
}

interface StaticRequire {
Expand Down Expand Up @@ -261,32 +261,28 @@ function defaultImageLoader(loaderProps: ImageLoaderProps) {

// See https://stackoverflow.com/q/39777833/266535 for why we use this ref
// handler instead of the img's onLoad attribute.
// 1500ms delay in removing placeholder is to prevent flash of white between
// image load and image render.
function removePlaceholder(
element: HTMLImageElement | null,
img: HTMLImageElement | null,
placeholder: PlaceholderValue
) {
if (placeholder === 'blur' && element) {
if (element.complete && !element.src.startsWith('data:')) {
if (placeholder === 'blur' && img) {
const handleLoad = () => {
if (!img.src.startsWith('data:')) {
const p = 'decode' in img ? img.decode() : Promise.resolve()
p.then(() => {
img.style.filter = 'none'
img.style.backgroundSize = 'none'
img.style.backgroundImage = 'none'
})
}
}
if (img.complete) {
// If the real image fails to load, this will still remove the placeholder.
// This is the desired behavior for now, and will be revisited when error
// handling is worked on for the image component itself.
setTimeout(() => {
element.style.filter = 'none'
element.style.backgroundSize = 'none'
element.style.backgroundImage = 'none'
}, 1500)
handleLoad()
} else {
element.onload = () => {
if (!element.src.startsWith('data:')) {
setTimeout(() => {
element.style.filter = 'none'
element.style.backgroundSize = 'none'
element.style.backgroundImage = 'none'
}, 1500)
}
}
img.onload = handleLoad
}
}
}
Expand Down Expand Up @@ -329,9 +325,7 @@ export default function Image({
)}`
)
}
if (staticImageData.placeholder) {
blurDataURL = staticImageData.placeholder
}
blurDataURL = blurDataURL || staticImageData.blurDataURL
staticSrc = staticImageData.src
if (!layout || layout !== 'fill') {
height = height || staticImageData.height
Expand All @@ -347,6 +341,10 @@ export default function Image({
}
src = typeof src === 'string' ? src : staticSrc

const widthInt = getInt(width)
const heightInt = getInt(height)
const qualityInt = getInt(quality)

if (process.env.NODE_ENV !== 'production') {
if (!src) {
throw new Error(
Expand Down Expand Up @@ -374,6 +372,27 @@ export default function Image({
`Image with src "${src}" has both "priority" and "loading='lazy'" properties. Only one should be used.`
)
}
if (placeholder === 'blur') {
if ((widthInt || 0) * (heightInt || 0) < 1600) {
console.warn(
`Image with src "${src}" is smaller than 40x40. Consider removing the "placeholder='blur'" property to improve performance.`
)
}
if (!blurDataURL) {
const VALID_BLUR_EXT = ['jpeg', 'png', 'webp'] // should match next-image-loader

throw new Error(
`Image with src "${src}" has "placeholder='blur'" property but is missing the "blurDataURL" property.
Possible solutions:
- Add a "blurDataURL" property, the contents should be a small Data URL to represent the image
- Change the "src" property to a static import with one of the supported file types: ${VALID_BLUR_EXT.join(
','
)}
- Remove the "placeholder" property, effectively no blur effect
Read more: https://nextjs.org/docs/messages/placeholder-blur-data-url`
)
}
}
}
let isLazy =
!priority && (loading === 'lazy' || typeof loading === 'undefined')
Expand All @@ -389,14 +408,6 @@ export default function Image({
})
const isVisible = !isLazy || isIntersected

const widthInt = getInt(width)
const heightInt = getInt(height)
const qualityInt = getInt(quality)

// Show blur if larger than 5000px such as 100 x 50
const showBlurPlaceholder =
placeholder === 'blur' && (widthInt || 0) * (heightInt || 0) > 5000

let wrapperStyle: JSX.IntrinsicElements['div']['style'] | undefined
let sizerStyle: JSX.IntrinsicElements['div']['style'] | undefined
let sizerSvg: string | undefined
Expand All @@ -423,7 +434,7 @@ export default function Image({
objectFit,
objectPosition,

...(showBlurPlaceholder
...(placeholder === 'blur'
? {
filter: 'blur(20px)',
backgroundSize: 'cover',
Expand Down
12 changes: 6 additions & 6 deletions packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -64,10 +64,10 @@
"dependencies": {
"@babel/runtime": "7.12.5",
"@hapi/accept": "5.0.2",
"@next/env": "10.2.4-canary.12",
"@next/polyfill-module": "10.2.4-canary.12",
"@next/react-dev-overlay": "10.2.4-canary.12",
"@next/react-refresh-utils": "10.2.4-canary.12",
"@next/env": "10.2.4-canary.13",
"@next/polyfill-module": "10.2.4-canary.13",
"@next/react-dev-overlay": "10.2.4-canary.13",
"@next/react-refresh-utils": "10.2.4-canary.13",
"assert": "2.0.0",
"ast-types": "0.13.2",
"browserify-zlib": "0.2.0",
Expand Down Expand Up @@ -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.4-canary.12",
"@next/polyfill-nomodule": "10.2.4-canary.13",
"@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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-dev-overlay",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"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
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-refresh-utils",
"version": "10.2.4-canary.12",
"version": "10.2.4-canary.13",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
Expand Down
Loading

0 comments on commit 8854ddd

Please sign in to comment.