Skip to content

Commit

Permalink
Merge branch 'canary' into custom-render-page-function
Browse files Browse the repository at this point in the history
  • Loading branch information
tz5514 committed Mar 22, 2018
2 parents 8649e43 + 930be28 commit 3d6601f
Show file tree
Hide file tree
Showing 567 changed files with 10,875 additions and 4,226 deletions.
8 changes: 7 additions & 1 deletion .github/issue_template.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<!--- Provide a general summary of the issue in the Title above -->

<!--
⚠️ IMPORTANT ⚠️
If you have a question about Next.js please ask it on Spectrum https://spectrum.chat/next-js
or join our Slack community at https://zeit.chat and ask it in the `#next` channel
-->

<!--
Thank you very much for contributing to Next.js by creating an issue! ❤️
To avoid duplicate issues we ask you to check off the following list
-->

<!-- Checked checkbox should look like this: [x] -->
- [ ] I have searched the [issues](https://github.com/zeit/next.js/issues) of this repository and believe that this is not a duplicate.
- [ ] I have searched the [issues](https://github.com/zeit/next.js/issues?q=is%3Aissue) of this repository and believe that this is not a duplicate.

## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ dist
# dependencies
node_modules
package-lock.json
test/node_modules

# logs
# logs & pids
*.log
pids

# coverage
.nyc_output
Expand Down
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
email: "leo@zeit.co",
tag: "canary",
api_key: {
secure:
"br9gLncKeLSoL7iOq0PXFeD1Gp3jRI8QMCSNIrGdZg/MuLeuwYPv36kmMgf7aGIfpjFLtU2/eVrOHSB+T5g1nKgOsqmWsfZE1tQYWph0//ookd/sj+IyxIx8nVLbUV/C4ctYOhX/efotRgNn56w5Av5hWc1IQLmW9mSN8ijrQnM+GzRI8QitiofeY2EP3N1eO8vC8E2oGkOsAdcypiX6lFG908zyWt7X2SD+iOsK2eAHjxoAEUdrxE5a8gTDhcTH6qnmtBs9rCeEKbO3JZjEy5dvccxlX3Nd+2GC1rckayk6o5L/zveTilsUx6Auqqbwn1dT5ffQuYsV4RPofs8IMrhnizc8y+OfUcCCpBJ4ia4w7N8FEP56TnRNTFoFBGJL5Y6NfeT0HHAlClxUWMG9pRGWGN+sskODDQ9FEntGZoqwV396ogs+3YhkxbY0AIr84QOctflsFcPtOgr/CoBeOsjbB+o9+Rlsqwlf3u3B7qhtU9eV6KcMfK4x9qW+2cwTllK+gD8S9wILx5BChkfx99g/7u/Rg1PCym64tTsDOBtqTVC2YCqeYYvjmpw4Vl3ofLrFsoNQnbmb6Q5+JSpOcJ/bEj7P/FuZdlU0fNV28tFhElu5caKhSCJz/avUlXG7NeveW1Ee8gjhURC4V/l4ryacyjA2vcDY/4RRkWtHNr4="
secure: "mvLXMXn1z1ri29wAy5/CCrDuO7ZC3gxckcnY5W00cbL8aFuK5buvpizKr3dz1pYX7vC55I+nZMtVa2vn4oOlTae07dd0BYGmmpiwq692XD4P+PHVs8D5MlbiT62vIJl/ezv/TcyoAbfIVPfUfLXA7H6a04Kodyzj3LffannOYpZNTPRNSdNAtkVtHPCuHksVpZoj6WhmC52MBEWkh0TCV3OdbeQAs6z3m6j81XcTduhXdraO4UmyXi/ML+eAgEBSejH70/7O/RSGludBOtIWMuxSrEey4wB4F4/xpN7k4LjPQRS+EtUBg9DSb3vB5y/hGwbDqwx7gGfN/yP/ssc9j3G8syTevv3fxH4ver9kg5tvltTJ8/gOzV7nF2sK1+Nb8legL4fLwHvgThf4sB9dAgNc7R8dYNgYwivkLUrrAy9WJsu7OsXLhg3NpEb9PcbKH7yFwrAzQjRPguVxg7bC02g41v0c2i1UXTb0D0/1KW5Mdg7HYZEw4uUXRhJCLWZbOcBCWdmiB+hwKSaq+aO49C5aX2UAyIsUPmG0OgqY91H/Y09KP3O6jN4j7ADrIIrdMwcyx15UJDZMwADCHHesnzeelDah7w3H6q+/heOA4nzbWhZaYQEDK4/aouRDINdXMmCmt9NNYjUA50BAI2dPpqetjaqq3gaPSAXsMvzNvRs="
},
skip_cleanup: true,
on: {
Expand Down
1 change: 1 addition & 0 deletions asset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dist/lib/asset')
9 changes: 3 additions & 6 deletions bin/next
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
#!/usr/bin/env node

import { join, resolve } from 'path'
import { join } from 'path'
import { spawn } from 'cross-spawn'
import { watchFile } from 'fs'
import pkg from '../../package.json'
import getConfig from '../server/config'

if (pkg.peerDependencies) {
Object.keys(pkg.peerDependencies).forEach(dependency => {
Expand Down Expand Up @@ -88,10 +85,10 @@ const startProcess = () => {
}

let proc = startProcess()
const { pagesDirectory = resolve(process.cwd(), 'pages') } = getConfig(process.cwd())

if (cmd === 'dev') {
watchFile(`${resolve(pagesDirectory, '..')}/next.config.js`, (cur, prev) => {
const {watchFile} = require('fs')
watchFile(`${process.cwd()}/next.config.js`, (cur, prev) => {
if (cur.size > 0 || prev.size > 0) {
console.log('\n> Found a change in next.config.js, restarting the server...')
// Don't listen to 'close' now since otherwise parent gets killed by listener
Expand Down
6 changes: 3 additions & 3 deletions bin/next-dev
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#!/usr/bin/env node
import 'source-map-support/register'
import { resolve, join } from 'path'
import parseArgs from 'minimist'
import { existsSync, readFileSync } from 'fs'
import Server from '../server'
import { printAndExit } from '../lib/utils'
import pkgUp from 'pkg-up'

const argv = parseArgs(process.argv.slice(2), {
alias: {
Expand Down Expand Up @@ -64,7 +62,9 @@ srv.start(argv.port, argv.hostname)
.catch((err) => {
if (err.code === 'EADDRINUSE') {
let errorMessage = `Port ${argv.port} is already in use.`
const pkgAppPath = pkgUp.sync('.')
const pkgAppPath = require('find-up').sync('package.json', {
cwd: dir
})
const appPackage = JSON.parse(readFileSync(pkgAppPath, 'utf8'))
const nextScript = Object.entries(appPackage.scripts).find(scriptLine => scriptLine[1] === 'next')
if (nextScript) errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p <some other port>\`.`
Expand Down
27 changes: 20 additions & 7 deletions client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import EventEmitter from '../lib/EventEmitter'
import App from '../lib/app'
import { loadGetInitialProps, getURL } from '../lib/utils'
import PageLoader from '../lib/page-loader'
import * as asset from '../lib/asset'
import * as envConfig from '../lib/runtime-config'

// Polyfill Promise globally
// This is needed because Webpack2's dynamic loading(common chunks) code
Expand All @@ -20,15 +22,28 @@ const {
__NEXT_DATA__: {
props,
err,
page,
pathname,
query,
buildId,
chunks,
assetPrefix
assetPrefix,
runtimeConfig
},
location
} = window

// With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
// So, this is how we do it in the client side at runtime
__webpack_public_path__ = `${assetPrefix}/_next/webpack/` //eslint-disable-line
// Initialize next/asset with the assetPrefix
asset.setAssetPrefix(assetPrefix)
// Initialize next/config with the environment configuration
envConfig.setConfig({
serverRuntimeConfig: {},
publicRuntimeConfig: runtimeConfig
})

const asPath = getURL()

const pageLoader = new PageLoader(buildId, assetPrefix)
Expand Down Expand Up @@ -69,7 +84,7 @@ export default async ({ ErrorDebugComponent: passedDebugComponent, stripAnsi: pa
ErrorComponent = await pageLoader.loadPage('/_error')

try {
Component = await pageLoader.loadPage(pathname)
Component = await pageLoader.loadPage(page)
} catch (err) {
console.error(stripAnsi(`${err.message}\n${err.stack}`))
Component = ErrorComponent
Expand All @@ -93,10 +108,7 @@ export default async ({ ErrorDebugComponent: passedDebugComponent, stripAnsi: pa
}

export async function render (props) {
// There are some errors we should ignore.
// Next.js rendering logic knows how to handle them.
// These are specially 404 errors
if (props.err && !props.err.ignore) {
if (props.err) {
await renderError(props.err)
return
}
Expand Down Expand Up @@ -159,7 +171,8 @@ async function doRender ({ Component, props, hash, err, emitter: emitterProp = e

let isInitialRender = true
function renderReactElement (reactEl, domEl) {
if (isInitialRender) {
// The check for `.hydrate` is there to support React alternatives like preact
if (isInitialRender && typeof ReactDOM.hydrate === 'function') {
ReactDOM.hydrate(reactEl, domEl)
isInitialRender = false
} else {
Expand Down
3 changes: 2 additions & 1 deletion client/next-dev.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'react-hot-loader/patch'
import stripAnsi from 'strip-ansi'
import initNext, * as next from './'
import ErrorDebugComponent from '../lib/error-debug'
import initOnDemandEntries from './on-demand-entries-client'
import initWebpackHMR from './webpack-hot-middleware-client'

require('@zeit/source-map-support/browser-source-map-support')

window.next = next

initNext({ ErrorDebugComponent, stripAnsi })
Expand Down
12 changes: 9 additions & 3 deletions client/on-demand-entries-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,29 @@
import Router from '../lib/router'
import fetch from 'unfetch'

const {
__NEXT_DATA__: {
assetPrefix
}
} = window

export default () => {
Router.ready(() => {
Router.router.events.on('routeChangeComplete', ping)
})

async function ping () {
try {
const url = `/_next/on-demand-entries-ping?page=${Router.pathname}`
const url = `${assetPrefix}/_next/on-demand-entries-ping?page=${Router.pathname}`
const res = await fetch(url, {
credentials: 'same-origin'
credentials: 'omit'
})
const payload = await res.json()
if (payload.invalid) {
// Payload can be invalid even if the page is not exists.
// So, we need to make sure it's exists before reloading.
const pageRes = await fetch(location.href, {
credentials: 'same-origin'
credentials: 'omit'
})
if (pageRes.status === 200) {
location.reload()
Expand Down
13 changes: 12 additions & 1 deletion client/webpack-hot-middleware-client.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?overlay=false&reload=true&path=/_next/webpack-hmr'
import 'event-source-polyfill'
import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?autoConnect=false&overlay=false&reload=true'
import Router from '../lib/router'

const {
__NEXT_DATA__: {
assetPrefix
}
} = window

export default () => {
webpackHotMiddlewareClient.setOptionsAndConnect({
path: `${assetPrefix}/_next/webpack-hmr`
})

const handlers = {
reload (route) {
if (route === '/_error') {
Expand Down
1 change: 1 addition & 0 deletions config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dist/lib/runtime-config')
1 change: 1 addition & 0 deletions constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dist/lib/constants')
1 change: 0 additions & 1 deletion css.js

This file was deleted.

25 changes: 25 additions & 0 deletions errors/no-on-app-updated-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Router.onAppUpdated is removed

Due to [this bug fix](https://github.com/zeit/next.js/pull/3849), we had to remove the `Router.onAppUpdated` hook. But the default functionality of this feature is still in effect.

We use this hook to detect a new app deployment when switching pages and act accordingly. Although there are many things you can do in this hook, it's often used to navigate the page via the server as shown below:

```js
Router.onAppUpdated = function(nextRoute) {
location.href = nextRoute
}
```

In this hook, you can't wait for a network request or a promise to get resolved. And you can't block the page navigation. So, the things you can do is limited.

One real use of this hook is to persist your application state to local-storage before the page navigation. For that, you can use the [`window.onbeforeunload`](https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload) hook instead.

This is code for that:

```js
window.onbeforeunload = function(e) {
// Get the application state (usually from a store like Redux)
const appState = {}
localStorage.setItem('app-state', JSON.stringify(appState));
};
```
7 changes: 4 additions & 3 deletions examples/active-class-name/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example:

```
npm i -g create-next-app
create-next-app --example active-class-name active-class-name-app
```bash
npx create-next-app --example active-class-name active-class-name-app
# or
yarn create next-app --example active-class-name active-class-name-app
```

### Download manually
Expand Down
4 changes: 2 additions & 2 deletions examples/active-class-name/components/Link.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import React, { Children } from 'react'
const ActiveLink = ({ router, children, ...props }) => {
const child = Children.only(children)

let className = child.props.className || ''
let className = child.props.className || null
if (router.pathname === props.href && props.activeClassName) {
className = `${className} ${props.activeClassName}`.trim()
className = `${className !== null ? className : ''} ${props.activeClassName}`.trim()
}

delete props.activeClassName
Expand Down
7 changes: 4 additions & 3 deletions examples/basic-css/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@

Download [`create-next-app`](https://github.com/segmentio/create-next-app) to bootstrap the example:

```
npm i -g create-next-app
create-next-app --example basic-css basic-css-app
```bash
npx create-next-app --example basic-css basic-css-app
# or
yarn create next-app --example basic-css basic-css-app
```

### Download manually
Expand Down
14 changes: 14 additions & 0 deletions examples/custom-charset/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "custom-server",
"version": "1.0.0",
"scripts": {
"dev": "node server.js",
"build": "next build",
"start": "NODE_ENV=production node server.js"
},
"dependencies": {
"next": "latest",
"react": "^16.0.0",
"react-dom": "^16.0.0"
}
}
34 changes: 34 additions & 0 deletions examples/custom-charset/pages/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/custom-server)

# Custom server example

## How to use

### Download manually

Download the example [or clone the repo](https://github.com/zeit/next.js):

```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/custom-charset
cd custom-charset
```

Install it and run:

```bash
npm install
npm run dev
```

Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))

```bash
now
```

## The idea behind the example

The HTTP/1.1 specification says - if charset is not set in the http header then the browser defaults use ISO-8859-1.
For languages like Polish, Albanian, Hungarian, Czech, Slovak, Slovene, there will be broken characters encoding from SSR.

You can overwrite Content-Type in getInitialProps. But if you want to handle it as a server side concern, you can use this as an simple example.
3 changes: 3 additions & 0 deletions examples/custom-charset/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import React from 'react'

export default () => <div>áéíóöúü</div>
21 changes: 21 additions & 0 deletions examples/custom-charset/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare()
.then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true)
res.setHeader('Content-Type', 'text/html; charset=iso-8859-2')
handle(req, res, parsedUrl)
})
.listen(port, (err) => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})
Loading

0 comments on commit 3d6601f

Please sign in to comment.