1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Merge branch 'canary' into block-node-env

This commit is contained in:
Connor Davis 2019-02-13 21:05:14 -06:00 committed by GitHub
commit 485909f76d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 203 additions and 21 deletions

View file

@ -765,7 +765,7 @@ class MyLink extends React.Component {
const { router } = this.props
router.prefetch('/dynamic')
}
render() {
const { router } = this.props
return (
@ -773,7 +773,7 @@ class MyLink extends React.Component {
<a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}>
A route transition will happen after 100ms
</a>
</div>
</div>
)
}
}
@ -1343,7 +1343,7 @@ module.exports = {
```js
// Example next.config.js for adding a loader that depends on babel-loader
// This source was taken from the @zeit/next-mdx plugin source:
// This source was taken from the @zeit/next-mdx plugin source:
// https://github.com/zeit/next-plugins/blob/master/packages/next-mdx
module.exports = {
webpack: (config, {}) => {
@ -1464,7 +1464,7 @@ module.exports = {
}
```
注意Next.js 运行时将会自动添加前缀,但是对于`/static`是没有效果的,如果你想这些静态资源也能使用 CDN你需要自己添加前缀。有一个方法可以判断你的环境来加前缀如 [in this example](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration)。
注意Next.js 运行时将会自动添加前缀,但是对于`/static`是没有效果的,如果你想这些静态资源也能使用 CDN你需要自己添加前缀。有一个方法可以判断你的环境来加前缀如 [in this example](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration-build-time)。
<a id="production-deployment" style="display: none"></a>
## 项目部署

View file

@ -41,4 +41,4 @@ now
This example shows how to import images, videos, etc. from `/static` and get the URL with a hash query allowing to use better cache without problems.
This example supports `.svg`, `.png` and `.txt` extensions, but it can be configured to support any possible extension changing the `extensions` array in the `.babelrc` file.
This example supports `.svg`, `.png` and `.txt` extensions, but it can be configured to support any possible extension changing the `extensions` array in the `next.config.js` [file](https://github.com/zeit/next.js/blob/canary/examples/with-hashed-statics/next.config.js#L4).

View file

@ -0,0 +1,23 @@
const webpack = require('webpack')
const nextSourceMaps = require('@zeit/next-source-maps')()
const SENTRY_DSN = ''
module.exports = nextSourceMaps({
webpack: (config, { dev, isServer, buildId }) => {
if (!dev) {
config.plugins.push(
new webpack.DefinePlugin({
'process.env.SENTRY_DSN': JSON.stringify(SENTRY_DSN),
'process.env.SENTRY_RELEASE': JSON.stringify(buildId)
})
)
}
if (!isServer) {
config.resolve.alias['@sentry/node'] = '@sentry/browser'
}
return config
}
})

View file

@ -1,23 +1,48 @@
import React from 'react'
import Link from 'next/link'
class Index extends React.Component {
static getInitialProps ({ query, req }) {
if (query.raiseError) {
throw new Error('Error in getInitialProps')
}
}
state = {
raiseError: false
}
componentDidUpdate () {
if (this.state.raiseError) {
throw new Error('Houston, we have a problem')
if (this.state.raiseErrorInUpdate) {
throw new Error('Error in componentDidUpdate')
}
}
raiseError = () => this.setState({ raiseError: true })
raiseErrorInUpdate = () => this.setState({ raiseErrorInUpdate: '1' })
raiseErrorInRender = () => this.setState({ raiseErrorInRender: '1' })
render () {
if (this.state.raiseErrorInRender) {
throw new Error('Error in render')
}
return (
<div>
<h2>Index page</h2>
<button onClick={this.raiseError}>Click to raise the error</button>
<ul>
<li><a href='#' onClick={this.raiseErrorInRender}>Raise the error in render</a></li>
<li><a href='#' onClick={this.raiseErrorInUpdate}>Raise the error in componentDidUpdate</a></li>
<li>
<Link href={{ pathname: '/', query: { raiseError: '1' } }}>
<a>Raise error in getInitialProps of client-loaded page</a>
</Link>
</li>
<li>
<a href='/?raiseError=1'>
Raise error in getInitialProps of server-loaded page
</a>
</li>
</ul>
</div>
)
}

View file

@ -0,0 +1,66 @@
const next = require('next')
const express = require('express')
const cookieParser = require('cookie-parser')
const Sentry = require('@sentry/node')
const uuidv4 = require('uuid/v4')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
require('./utils/sentry')
app.prepare()
.then(() => {
const server = express()
// This attaches request information to sentry errors
server.use(Sentry.Handlers.requestHandler())
server.use(cookieParser())
server.use((req, res, next) => {
const htmlPage =
!req.path.match(/^\/(_next|static)/) &&
!req.path.match(/\.(js|map)$/) &&
req.accepts('text/html', 'text/css', 'image/png') === 'text/html'
if (!htmlPage) {
next()
return
}
if (!req.cookies.sid || req.cookies.sid.length === 0) {
req.cookies.sid = uuidv4()
res.cookie('sid', req.cookies.sid)
}
next()
})
// In production we don't want to serve sourcemaps for anyone
if (!dev) {
const hasSentryToken = !!process.env.SENTRY_TOKEN
server.get(/\.map$/, (req, res, next) => {
if (hasSentryToken && req.headers['x-sentry-token'] !== process.env.SENTRY_TOKEN) {
res
.status(401)
.send(
'Authentication access token is required to access the source map.'
)
return
}
next()
})
}
server.get('*', (req, res) => handle(req, res))
// This handles errors if they are thrown before raching the app
server.use(Sentry.Handlers.errorHandler())
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
})

View file

@ -0,0 +1,63 @@
const Sentry = require('@sentry/node')
const Cookie = require('js-cookie')
if (process.env.SENTRY_DSN) {
Sentry.init({
dsn: process.env.SENTRY_DSN,
release: process.env.SENTRY_RELEASE,
maxBreadcrumbs: 50,
attachStacktrace: true
})
}
function captureException (err, { req, res, errorInfo, query, pathname }) {
Sentry.configureScope(scope => {
if (err.message) {
// De-duplication currently doesn't work correctly for SSR / browser errors
// so we force deduplication by error message if it is present
scope.setFingerprint([err.message])
}
if (err.statusCode) {
scope.setExtra('statusCode', err.statusCode)
}
if (res && res.statusCode) {
scope.setExtra('statusCode', res.statusCode)
}
if (process.browser) {
scope.setTag('ssr', false)
scope.setExtra('query', query)
scope.setExtra('pathname', pathname)
// On client-side we use js-cookie package to fetch it
const sessionId = Cookie.get('sid')
if (sessionId) {
scope.setUser({ id: sessionId })
}
} else {
scope.setTag('ssr', true)
scope.setExtra('url', req.url)
scope.setExtra('method', req.method)
scope.setExtra('headers', req.headers)
scope.setExtra('params', req.params)
scope.setExtra('query', req.query)
// On server-side we take session cookie directly from request
if (req.cookies.sid) {
scope.setUser({ id: req.cookies.sid })
}
}
if (errorInfo) {
scope.setExtra('componentStack', errorInfo.componentStack)
}
})
Sentry.captureException(err)
}
module.exports = {
captureException
}

View file

@ -1,6 +1,7 @@
@import "./button.css";
@tailwind preflight;
@tailwind components;
@tailwind utilities;
.hero {

View file

@ -10,9 +10,12 @@
},
"publish": {
"npmClient": "npm",
"allowBranch": "canary",
"allowBranch": [
"master",
"canary"
],
"registry": "https://registry.npmjs.org/"
}
},
"version": "8.0.0-canary.24"
"version": "8.0.1-canary.0"
}

View file

@ -19,6 +19,7 @@
"typescript": "lerna run typescript",
"prepublish": "lerna run prepublish",
"publish-canary": "lerna version prerelease --preid canary --force-publish && release --pre",
"publish-stable": "lerna version --force-publish",
"lint-staged": "lint-staged"
},
"pre-commit": "lint-staged",

View file

@ -1,6 +1,6 @@
{
"name": "next-server",
"version": "8.0.0-canary.24",
"version": "8.0.1-canary.0",
"main": "./index.js",
"license": "MIT",
"files": [

View file

@ -836,7 +836,7 @@ You can add `prefetch` prop to any `<Link>` and Next.js will prefetch those page
```jsx
import Link from 'next/link'
function Header() {
function Header() {
return (
<nav>
<ul>
@ -870,7 +870,7 @@ Most prefetching needs are addressed by `<Link />`, but we also expose an impera
```jsx
import { withRouter } from 'next/router'
function MyLink({ router }) {
function MyLink({ router }) {
return (
<div>
<a onClick={() => setTimeout(() => router.push('/dynamic'), 100)}>
@ -1082,7 +1082,7 @@ function Home() {
<p>HOME PAGE is here!</p>
</div>
)
}
}
export default Home
```
@ -1575,7 +1575,7 @@ Example usage of `defaultLoaders.babel`:
// This source was taken from the @zeit/next-mdx plugin source:
// https://github.com/zeit/next-plugins/blob/master/packages/next-mdx
module.exports = {
webpack: (config, {}) => {
webpack: (config, options) => {
config.module.rules.push({
test: /\.mdx/,
use: [
@ -1684,10 +1684,10 @@ export default Index
> :warning: Note that this option is not available when using `target: 'serverless'`
> :warning: Generally you want to use build-time configuration to provide your configuration.
> :warning: Generally you want to use build-time configuration to provide your configuration.
The reason for this is that runtime configuration adds a small rendering / initialization overhead.
The `next/config` module gives your app access to the `publicRuntimeConfig` and `serverRuntimeConfig` stored in your `next.config.js`.
The `next/config` module gives your app access to the `publicRuntimeConfig` and `serverRuntimeConfig` stored in your `next.config.js`.
Place any server-only runtime config under a `serverRuntimeConfig` property.
@ -1742,7 +1742,7 @@ module.exports = {
}
```
Note: Next.js will automatically use that prefix in the scripts it loads, but this has no effect whatsoever on `/static`. If you want to serve those assets over the CDN, you'll have to introduce the prefix yourself. One way of introducing a prefix that works inside your components and varies by environment is documented [in this example](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration).
Note: Next.js will automatically use that prefix in the scripts it loads, but this has no effect whatsoever on `/static`. If you want to serve those assets over the CDN, you'll have to introduce the prefix yourself. One way of introducing a prefix that works inside your components and varies by environment is documented [in this example](https://github.com/zeit/next.js/tree/master/examples/with-universal-configuration-build-time).
If your CDN is on a separate domain and you would like assets to be requested using a [CORS aware request](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) you can set a config option for that.

View file

@ -1,6 +1,6 @@
{
"name": "next",
"version": "8.0.0-canary.24",
"version": "8.0.1-canary.0",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
@ -72,7 +72,7 @@
"loader-utils": "1.1.0",
"mkdirp-then": "1.2.0",
"nanoid": "1.2.1",
"next-server": "8.0.0-canary.24",
"next-server": "8.0.1-canary.0",
"prop-types": "15.6.2",
"prop-types-exact": "1.2.0",
"react-error-overlay": "4.0.0",