Skip to content

Commit 5577efa

Browse files
authored
Merge branch 'canary' into feat-swc-experimental-plugin
2 parents 00a6d3d + e4a9f09 commit 5577efa

File tree

10 files changed

+72
-86
lines changed

10 files changed

+72
-86
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ Choose the right checklist for the change that you're making:
2222
## Documentation / Examples
2323

2424
- [ ] Make sure the linting passes by running `yarn lint`
25+
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)

.github/workflows/build_test_deploy.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -635,10 +635,6 @@ jobs:
635635
path: ./*
636636
key: ${{ github.sha }}-${{ github.run_number }}
637637

638-
- uses: pnpm/[email protected]
639-
with:
640-
version: 6.32.2
641-
642638
- uses: actions/download-artifact@v3
643639
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
644640
with:

contributing.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,17 @@ Below are the steps to add a new link:
265265

266266
## Adding examples
267267

268-
When you add an example to the [examples](examples) directory, don’t forget to add a `README.md` file with the following format:
268+
When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high quality examples:
269+
270+
- TypeScript should be leveraged for new examples (no need for separate JavaScript and TypeScript examples)
271+
- Examples should not add custom ESLint configuration (we have specific templates for ESLint)
272+
- If API routes aren't used in an example, they should be omitted
273+
- If an example exists for a certain library and you would like to showcase a specific feature of that library, the existing example should be updated (instead of adding a new example)
274+
- Package manager specific config should not be added (e.g. `resolutions` in `package.json`)
275+
- In `package.json` the version of `next` (and `eslint-config-next`) should be `latest`
276+
- In `package.json` the dependency versions should be up-to-date
277+
278+
Also don’t forget to add a `README.md` file with the following format:
269279

270280
- Replace `DIRECTORY_NAME` with the directory name you’re adding.
271281
- Fill in `Example Name` and `Description`.

docs/api-reference/next/image.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ When using `layout="intrinsic"`, `layout="fixed"`, or `layout="raw"`, the `width
5555

5656
When using `layout="responsive"`, `layout="fill"`, the `width` property represents the _original_ width in pixels, so it will only affect the aspect ratio.
5757

58-
The `width` property is required, except for [statically imported images](#local-images), or those with `layout="fill"`.
58+
The `width` property is required, except for [statically imported images](/docs/basic-features/image-optimization.md#local-images), or those with `layout="fill"`.
5959

6060
### height
6161

@@ -65,7 +65,7 @@ When using `layout="intrinsic"`, `layout="fixed"`, or `layout="raw"`, the `heigh
6565

6666
When using `layout="responsive"`, `layout="fill"`, the `height` property represents the _original_ height in pixels, so it will only affect the aspect ratio.
6767

68-
The `height` property is required, except for [statically imported images](#local-images), or those with `layout="fill"`.
68+
The `height` property is required, except for [statically imported images](/docs/basic-features/image-optimization.md#local-images), or those with `layout="fill"`.
6969

7070
## Optional Props
7171

examples/cms-kontent/components/image.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
import NextImage from 'next/image'
22
import { transformImageUrl } from '@kentico/kontent-delivery'
33

4-
const KONTENT_ASSET_HOSTNAME_REGEX = /.kc-usercontent.com$/
5-
64
const getLoader = (src) => {
75
return srcIsKontentAsset(src) ? kontentImageLoader : undefined
86
}
97

108
const srcIsKontentAsset = (src) => {
119
try {
1210
const { hostname } = new URL(src)
13-
return KONTENT_ASSET_HOSTNAME_REGEX.test(hostname)
11+
return hostname.endsWith('.kc-usercontent.com')
1412
} catch {
1513
return false
1614
}
1715
}
1816

19-
const kontentImageLoader = ({ src, width, quality = 100 }) => {
17+
const kontentImageLoader = ({ src, width, quality = 75 }) => {
2018
return new transformImageUrl(src)
2119
.withWidth(width)
2220
.withQuality(quality)

examples/cms-kontent/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"devDependencies": {
2020
"autoprefixer": "10.4.7",
2121
"postcss": "8.4.14",
22-
"tailwindcss": "^3.0.15"
22+
"tailwindcss": "^3.0.15",
23+
"tslib": "2.4.0"
2324
}
2425
}

packages/next/client/app-index.tsx

Lines changed: 43 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ import '../build/polyfills/polyfill-module'
33
// @ts-ignore react-dom/client exists when using React 18
44
import ReactDOMClient from 'react-dom/client'
55
// @ts-ignore startTransition exists when using React 18
6-
import React, { useState, startTransition } from 'react'
7-
import { RefreshContext } from './streaming/refresh'
8-
import { createFromFetch } from 'next/dist/compiled/react-server-dom-webpack'
6+
import React from 'react'
7+
import {
8+
createFromFetch,
9+
createFromReadableStream,
10+
} from 'next/dist/compiled/react-server-dom-webpack'
911

1012
/// <reference types="react-dom/experimental" />
1113

@@ -36,7 +38,8 @@ const getCacheKey = () => {
3638
const encoder = new TextEncoder()
3739

3840
let initialServerDataBuffer: string[] | undefined = undefined
39-
let initialServerDataWriter: WritableStreamDefaultWriter | undefined = undefined
41+
let initialServerDataWriter: ReadableStreamDefaultController | undefined =
42+
undefined
4043
let initialServerDataLoaded = false
4144
let initialServerDataFlushed = false
4245

@@ -48,7 +51,7 @@ function nextServerDataCallback(seg: [number, string, string]) {
4851
throw new Error('Unexpected server data: missing bootstrap script.')
4952

5053
if (initialServerDataWriter) {
51-
initialServerDataWriter.write(encoder.encode(seg[2]))
54+
initialServerDataWriter.enqueue(encoder.encode(seg[2]))
5255
} else {
5356
initialServerDataBuffer.push(seg[2])
5457
}
@@ -63,19 +66,19 @@ function nextServerDataCallback(seg: [number, string, string]) {
6366
// Hence, we use two variables `initialServerDataLoaded` and
6467
// `initialServerDataFlushed` to make sure the writer will be closed and
6568
// `initialServerDataBuffer` will be cleared in the right time.
66-
function nextServerDataRegisterWriter(writer: WritableStreamDefaultWriter) {
69+
function nextServerDataRegisterWriter(ctr: ReadableStreamDefaultController) {
6770
if (initialServerDataBuffer) {
6871
initialServerDataBuffer.forEach((val) => {
69-
writer.write(encoder.encode(val))
72+
ctr.enqueue(encoder.encode(val))
7073
})
7174
if (initialServerDataLoaded && !initialServerDataFlushed) {
72-
writer.close()
75+
ctr.close()
7376
initialServerDataFlushed = true
7477
initialServerDataBuffer = undefined
7578
}
7679
}
7780

78-
initialServerDataWriter = writer
81+
initialServerDataWriter = ctr
7982
}
8083

8184
// When `DOMContentLoaded`, we can close all pending writers to finish hydration.
@@ -104,54 +107,26 @@ function createResponseCache() {
104107
}
105108
const rscCache = createResponseCache()
106109

107-
function fetchFlight(href: string, props?: any) {
108-
const url = new URL(href, location.origin)
109-
const searchParams = url.searchParams
110-
searchParams.append('__flight__', '1')
111-
if (props) {
112-
searchParams.append('__props__', JSON.stringify(props))
113-
}
114-
return fetch(url.toString())
115-
}
116-
117-
function useServerResponse(cacheKey: string, serialized?: string) {
118-
let response = rscCache.get(cacheKey)
110+
function useInitialServerResponse(cacheKey: string) {
111+
const response = rscCache.get(cacheKey)
119112
if (response) return response
120113

121-
if (initialServerDataBuffer) {
122-
const t = new TransformStream()
123-
const writer = t.writable.getWriter()
124-
response = createFromFetch(Promise.resolve({ body: t.readable }))
125-
nextServerDataRegisterWriter(writer)
126-
} else {
127-
const fetchPromise = serialized
128-
? (() => {
129-
const t = new TransformStream()
130-
const writer = t.writable.getWriter()
131-
writer.ready.then(() => {
132-
writer.write(new TextEncoder().encode(serialized))
133-
})
134-
return Promise.resolve({ body: t.readable })
135-
})()
136-
: fetchFlight(getCacheKey())
137-
response = createFromFetch(fetchPromise)
138-
}
114+
const readable = new ReadableStream({
115+
start(controller) {
116+
nextServerDataRegisterWriter(controller)
117+
},
118+
})
119+
const newResponse = createFromReadableStream(readable)
139120

140-
rscCache.set(cacheKey, response)
141-
return response
121+
rscCache.set(cacheKey, newResponse)
122+
return newResponse
142123
}
143124

144-
const ServerRoot = ({
145-
cacheKey,
146-
serialized,
147-
}: {
148-
cacheKey: string
149-
serialized?: string
150-
}) => {
125+
const ServerRoot = ({ cacheKey }: { cacheKey: string }) => {
151126
React.useEffect(() => {
152127
rscCache.delete(cacheKey)
153128
})
154-
const response = useServerResponse(cacheKey, serialized)
129+
const response = useInitialServerResponse(cacheKey)
155130
const root = response.readRoot()
156131
return root
157132
}
@@ -171,27 +146,27 @@ function Root({ children }: React.PropsWithChildren<{}>): React.ReactElement {
171146
return children as React.ReactElement
172147
}
173148

174-
const RSCComponent = (props: any) => {
149+
const RSCComponent = () => {
175150
const cacheKey = getCacheKey()
176-
const { __flight_serialized__ } = props
177-
const [, dispatch] = useState({})
178-
const rerender = () => dispatch({})
179-
// If there is no cache, or there is serialized data already
180-
function refreshCache(nextProps: any) {
181-
startTransition(() => {
182-
const currentCacheKey = getCacheKey()
183-
const response = createFromFetch(fetchFlight(currentCacheKey, nextProps))
184-
185-
rscCache.set(currentCacheKey, response)
186-
rerender()
187-
})
188-
}
151+
return <ServerRoot cacheKey={cacheKey} />
152+
}
189153

190-
return (
191-
<RefreshContext.Provider value={refreshCache}>
192-
<ServerRoot cacheKey={cacheKey} serialized={__flight_serialized__} />
193-
</RefreshContext.Provider>
194-
)
154+
function fetchFlight(href: string) {
155+
const url = new URL(href, location.origin)
156+
const searchParams = url.searchParams
157+
searchParams.append('__flight__', '1')
158+
159+
return fetch(url.toString())
160+
}
161+
162+
function useServerResponse(cacheKey: string) {
163+
let response = rscCache.get(cacheKey)
164+
if (response) return response
165+
166+
response = createFromFetch(fetchFlight(getCacheKey()))
167+
168+
rscCache.set(cacheKey, response)
169+
return response
195170
}
196171

197172
const AppRouterContext = React.createContext({})

packages/next/server/app-render.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,6 @@ export async function renderToHTML(
372372
}
373373
)
374374

375-
// const serverComponentProps = query.__props__
376-
// ? JSON.parse(query.__props__ as string)
377-
// : undefined
378-
379375
const jsxStyleRegistry = createStyleRegistry()
380376

381377
const styledJsxFlushEffect = () => {

packages/next/shared/lib/loadable.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
2222
// Modified to be compatible with webpack 4 / Next.js
2323

2424
import React from 'react'
25-
import { useSyncExternalStore } from 'use-sync-external-store/shim'
26-
2725
import { LoadableContext } from './loadable-context'
2826

27+
const { useSyncExternalStore } = process.env.__NEXT_REACT_ROOT
28+
? require('react')
29+
: require('use-sync-external-store/shim')
30+
2931
const ALL_INITIALIZERS = []
3032
const READY_INITIALIZERS = []
3133
let initialized = false

test/integration/create-next-app/index.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,13 @@ describe('create next app', () => {
431431
})
432432

433433
it('should use pnpm as the package manager on supplying --use-pnpm with example', async () => {
434+
try {
435+
await execa('pnpm', ['--version'])
436+
} catch (_) {
437+
// install pnpm if not available
438+
await execa('npm', ['i', '-g', 'pnpm'])
439+
}
440+
434441
await usingTempDir(async (cwd) => {
435442
const projectName = 'use-pnpm'
436443
const res = await run(

0 commit comments

Comments
 (0)