mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Merge master into dynamic-import.
This commit is contained in:
commit
90ea471aa7
6
bin/next
6
bin/next
|
@ -1,9 +1,10 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
import { join } from 'path'
|
||||
import { join, resolve } 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 => {
|
||||
|
@ -78,9 +79,10 @@ const startProcess = () => {
|
|||
}
|
||||
|
||||
let proc = startProcess()
|
||||
const { pagesDirectory = resolve(process.cwd(), 'pages') } = getConfig(process.cwd())
|
||||
|
||||
if (cmd === 'dev') {
|
||||
watchFile(join(process.cwd(), 'next.config.js'), (cur, prev) => {
|
||||
watchFile(`${resolve(pagesDirectory, '..')}/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
|
||||
|
|
|
@ -24,12 +24,13 @@ const {
|
|||
pathname,
|
||||
query,
|
||||
buildId,
|
||||
chunks
|
||||
chunks,
|
||||
assetPrefix
|
||||
},
|
||||
location
|
||||
} = window
|
||||
|
||||
const pageLoader = new PageLoader(buildId)
|
||||
const pageLoader = new PageLoader(buildId, assetPrefix)
|
||||
window.__NEXT_LOADED_PAGES__.forEach(({ route, fn }) => {
|
||||
pageLoader.registerPage(route, fn)
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?overlay=false&reload=true'
|
||||
import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?overlay=false&reload=true&path=/_next/webpack-hmr'
|
||||
import Router from '../lib/router'
|
||||
|
||||
export default () => {
|
||||
|
|
|
@ -12,14 +12,16 @@ const match = route('/blog/:id')
|
|||
app.prepare()
|
||||
.then(() => {
|
||||
createServer((req, res) => {
|
||||
const { pathname } = parse(req.url)
|
||||
const { pathname, query } = parse(req.url, true)
|
||||
const params = match(pathname)
|
||||
if (params === false) {
|
||||
handle(req, res)
|
||||
return
|
||||
}
|
||||
|
||||
app.render(req, res, '/blog', params)
|
||||
// assigning `query` into the params means that we still
|
||||
// get the query string passed to our application
|
||||
// i.e. /blog/foo?show-comments=true
|
||||
app.render(req, res, '/blog', Object.assign(params, query))
|
||||
})
|
||||
.listen(3000, (err) => {
|
||||
if (err) throw err
|
||||
|
|
|
@ -37,7 +37,7 @@ Another babel plugin [module-resolver](https://github.com/tleunen/babel-plugin-m
|
|||
|
||||
The `sass-loader` is configured with `includePaths: ['styles', 'node_modules']` so that your scss can `@import` from those places, again without relative paths, for maximum convenience and ability to use npm-published libraries. Furthermore, `glob` paths are also supported, so one could for example add `'node_modules/@material/*'` to the `includePaths`, which would make [material-components-web](https://github.com/material-components/material-components-web) (if you'd like) even easier to work with.
|
||||
|
||||
Furthermore, PostCSS is used to [pre-process](https://blog.madewithenvy.com/webpack-2-postcss-cssnext-fdcd2fd7d0bd#.r6t2d0smy) both `css` and `scss` stylesheets, the latter after Sass pre-processing. This is to illustrate `@import 'normalize.css';` from `node_modules` thanks to `postcss-easy-import`. [Autoprefixer](https://github.com/postcss/autoprefixer) is also added as a "best practice". Consider [cssnext](http://cssnext.io) instead, which includes `autoprefixer` as well as many other CSS spec features.
|
||||
Furthermore, PostCSS is used to [pre-process](https://medium.com/@ddprrt/deconfusing-pre-and-post-processing-d68e3bd078a3) both `css` and `scss` stylesheets, the latter after Sass pre-processing. This is to illustrate `@import 'normalize.css';` from `node_modules` thanks to `postcss-easy-import`. [Autoprefixer](https://github.com/postcss/autoprefixer) is also added as a "best practice". Consider [cssnext](http://cssnext.io) instead, which includes `autoprefixer` as well as many other CSS spec features.
|
||||
|
||||
This project shows how you can set it up. Have a look at:
|
||||
- .babelrc
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"express": "^4.15.2",
|
||||
"next": "^2.0.0",
|
||||
"next-url-prettifier": "^1.0.2",
|
||||
"prop-types": "^15.5.6",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {Link} from 'next-url-prettifier'
|
||||
import {Router} from '../routes'
|
||||
|
||||
|
@ -29,6 +30,6 @@ export default class GreetingPage extends React.Component {
|
|||
}
|
||||
|
||||
GreetingPage.propTypes = {
|
||||
lang: React.PropTypes.string,
|
||||
name: React.PropTypes.string
|
||||
lang: PropTypes.string,
|
||||
name: PropTypes.string
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { Component, PropTypes } from 'react'
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { AppContainer } from 'react-hot-loader'
|
||||
import shallowEquals from './shallow-equals'
|
||||
import { warn } from './utils'
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import sideEffect from './side-effect'
|
||||
|
||||
class Head extends React.Component {
|
||||
static contextTypes = {
|
||||
headManager: React.PropTypes.object
|
||||
headManager: PropTypes.object
|
||||
}
|
||||
|
||||
render () {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { resolve, format, parse } from 'url'
|
||||
import React, { Component, Children, PropTypes } from 'react'
|
||||
import React, { Component, Children } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import Router from './router'
|
||||
import { warn, execOnce, getLocationOrigin } from './utils'
|
||||
|
||||
|
|
|
@ -4,8 +4,10 @@ import mitt from 'mitt'
|
|||
const webpackModule = module
|
||||
|
||||
export default class PageLoader {
|
||||
constructor (buildId) {
|
||||
constructor (buildId, assetPrefix) {
|
||||
this.buildId = buildId
|
||||
this.assetPrefix = assetPrefix
|
||||
|
||||
this.pageCache = {}
|
||||
this.pageLoadedHandlers = {}
|
||||
this.pageRegisterEvents = mitt()
|
||||
|
@ -59,7 +61,7 @@ export default class PageLoader {
|
|||
route = this.normalizeRoute(route)
|
||||
|
||||
const script = document.createElement('script')
|
||||
const url = `/_next/${encodeURIComponent(this.buildId)}/page${route}`
|
||||
const url = `${this.assetPrefix}/_next/${encodeURIComponent(this.buildId)}/page${route}`
|
||||
script.src = url
|
||||
script.type = 'text/javascript'
|
||||
script.onerror = () => {
|
||||
|
|
|
@ -81,8 +81,8 @@ export default class Router {
|
|||
|
||||
if (route !== this.route) return
|
||||
|
||||
const { pathname, query } = this
|
||||
const url = window.location.href
|
||||
const { pathname, query } = parse(url, true)
|
||||
|
||||
this.events.emit('routeChangeStart', url)
|
||||
const routeInfo = await this.getRouteInfo(route, pathname, query, url)
|
||||
|
|
22
package.json
22
package.json
|
@ -1,13 +1,10 @@
|
|||
{
|
||||
"name": "next",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.1",
|
||||
"description": "Minimalistic framework for server-rendered React applications",
|
||||
"main": "./dist/server/next.js",
|
||||
"license": "MIT",
|
||||
"repository": "zeit/next.js",
|
||||
"publishConfig": {
|
||||
"tag": "beta"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"babel.js",
|
||||
|
@ -57,17 +54,19 @@
|
|||
"babel-plugin-transform-es2015-modules-commonjs": "6.24.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.22.0",
|
||||
"babel-plugin-transform-react-jsx-source": "6.22.0",
|
||||
"babel-plugin-transform-react-remove-prop-types": "0.3.2",
|
||||
"babel-plugin-transform-react-remove-prop-types": "0.4.0",
|
||||
"babel-plugin-transform-runtime": "6.22.0",
|
||||
"babel-preset-latest": "6.24.0",
|
||||
"babel-preset-env": "1.3.3",
|
||||
"babel-preset-react": "6.23.0",
|
||||
"babel-runtime": "6.23.0",
|
||||
"babel-template": "6.24.1",
|
||||
"case-sensitive-paths-webpack-plugin": "2.0.0",
|
||||
"cross-spawn": "5.1.0",
|
||||
"del": "2.2.2",
|
||||
"etag": "1.8.0",
|
||||
"fresh": "0.5.0",
|
||||
"friendly-errors-webpack-plugin": "1.5.0",
|
||||
"glob": "^7.1.1",
|
||||
"glob": "7.1.1",
|
||||
"glob-promise": "3.1.0",
|
||||
"htmlescape": "1.1.1",
|
||||
"http-status": "1.0.1",
|
||||
|
@ -82,6 +81,7 @@
|
|||
"mz": "2.6.0",
|
||||
"path-match": "1.2.4",
|
||||
"pkg-up": "1.0.0",
|
||||
"prop-types": "15.5.7",
|
||||
"react-hot-loader": "3.0.0-beta.6",
|
||||
"send": "0.15.1",
|
||||
"source-map-support": "0.4.14",
|
||||
|
@ -97,14 +97,14 @@
|
|||
"write-file-webpack-plugin": "4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "7.2.0",
|
||||
"babel-eslint": "7.2.2",
|
||||
"babel-jest": "18.0.0",
|
||||
"babel-plugin-istanbul": "4.1.1",
|
||||
"babel-plugin-transform-remove-strict-mode": "0.0.2",
|
||||
"babel-preset-es2015": "6.24.0",
|
||||
"benchmark": "2.1.4",
|
||||
"cheerio": "0.22.0",
|
||||
"chromedriver": "2.28.0",
|
||||
"chromedriver": "2.29.0",
|
||||
"coveralls": "2.13.0",
|
||||
"cross-env": "4.0.0",
|
||||
"fly": "2.0.5",
|
||||
|
@ -118,8 +118,8 @@
|
|||
"node-fetch": "1.6.3",
|
||||
"node-notifier": "5.1.2",
|
||||
"nyc": "10.2.0",
|
||||
"react": "15.4.2",
|
||||
"react-dom": "15.4.2",
|
||||
"react": "15.5.3",
|
||||
"react-dom": "15.5.3",
|
||||
"standard": "9.0.2",
|
||||
"wd": "1.2.0"
|
||||
},
|
||||
|
|
27
readme.md
27
readme.md
|
@ -11,6 +11,7 @@ Next.js is a minimalistic framework for server-rendered React applications.
|
|||
<!-- https://github.com/thlorenz/doctoc -->
|
||||
|
||||
- [How to use](#how-to-use)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Setup](#setup)
|
||||
- [Automatic code splitting](#automatic-code-splitting)
|
||||
- [CSS](#css)
|
||||
|
@ -33,9 +34,9 @@ Next.js is a minimalistic framework for server-rendered React applications.
|
|||
- [Custom configuration](#custom-configuration)
|
||||
- [Customizing webpack config](#customizing-webpack-config)
|
||||
- [Customizing babel config](#customizing-babel-config)
|
||||
- [CDN support with Asset Prefix](#cdn-support-with-asset-prefix)
|
||||
- [Production deployment](#production-deployment)
|
||||
- [FAQ](#faq)
|
||||
- [Roadmap](#roadmap)
|
||||
- [Contributing](#contributing)
|
||||
- [Authors](#authors)
|
||||
|
||||
|
@ -43,6 +44,10 @@ Next.js is a minimalistic framework for server-rendered React applications.
|
|||
|
||||
## How to use
|
||||
|
||||
### Getting Started
|
||||
|
||||
A step by step interactive guide of next features is available at [learnnextjs.com](https://learnnextjs.com/)
|
||||
|
||||
### Setup
|
||||
|
||||
Install it:
|
||||
|
@ -298,7 +303,7 @@ The component `<Link>` can also receive an URL object and it will automatically
|
|||
// pages/index.js
|
||||
import Link from 'next/link'
|
||||
export default () => (
|
||||
<div>Click <Link href={{ pathname: 'about', query: { name: 'Zeit' }}}<a>here</a></Link> to read more</div>
|
||||
<div>Click <Link href={{ pathname: 'about', query: { name: 'Zeit' }}}><a>here</a></Link> to read more</div>
|
||||
)
|
||||
```
|
||||
|
||||
|
@ -700,6 +705,20 @@ Here's an example `.babelrc` file:
|
|||
}
|
||||
```
|
||||
|
||||
### CDN support with Asset Prefix
|
||||
|
||||
To set up a CDN, you can set up the `assetPrefix` setting and configure your CDN's origin to resolve to the domain that Next.js is hosted on.
|
||||
|
||||
```js
|
||||
const isProd = process.NODE_ENV === 'production'
|
||||
module.exports = {
|
||||
// You may only need to add assetPrefix in the production.
|
||||
assetPrefix: isProd ? 'https://cdn.mydomain.com' : ''
|
||||
}
|
||||
```
|
||||
|
||||
Note: Next.js will automatically use that prefix 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).
|
||||
|
||||
## Production deployment
|
||||
|
||||
To deploy, instead of running `next`, you want to build for production usage ahead of time. Therefore, building and starting are separate commands:
|
||||
|
@ -840,10 +859,6 @@ As we were researching options for server-rendering React that didn’t involve
|
|||
|
||||
</details>
|
||||
|
||||
## Roadmap
|
||||
|
||||
Our Roadmap towards 2.0.0 [is public](https://github.com/zeit/next.js/wiki/Roadmap#nextjs-200).
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see our [contributing.md](./contributing.md)
|
||||
|
|
|
@ -13,8 +13,8 @@ const plugins = envPlugins[process.env.NODE_ENV] || []
|
|||
|
||||
module.exports = {
|
||||
presets: [
|
||||
[require.resolve('babel-preset-latest'), {
|
||||
'es2015': { modules: false }
|
||||
[require.resolve('babel-preset-env'), {
|
||||
modules: false
|
||||
}],
|
||||
require.resolve('babel-preset-react')
|
||||
],
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { tmpdir } from 'os'
|
||||
import { join } from 'path'
|
||||
import getConfig from '../config'
|
||||
import fs from 'mz/fs'
|
||||
import uuid from 'uuid'
|
||||
import del from 'del'
|
||||
|
@ -14,10 +13,8 @@ export default async function build (dir) {
|
|||
|
||||
try {
|
||||
await runCompiler(compiler)
|
||||
|
||||
// Pass in both the buildDir and the dir to retrieve config
|
||||
await writeBuildStats(buildDir, dir)
|
||||
await writeBuildId(buildDir, dir)
|
||||
await writeBuildStats(buildDir)
|
||||
await writeBuildId(buildDir)
|
||||
} catch (err) {
|
||||
console.error(`> Failed to build on ${buildDir}`)
|
||||
throw err
|
||||
|
@ -48,24 +45,22 @@ function runCompiler (compiler) {
|
|||
})
|
||||
}
|
||||
|
||||
async function writeBuildStats (buildDir, dir) {
|
||||
const dist = getConfig(dir).distDir
|
||||
async function writeBuildStats (dir) {
|
||||
// Here we can't use hashes in webpack chunks.
|
||||
// That's because the "app.js" is not tied to a chunk.
|
||||
// It's created by merging a few assets. (commons.js and main.js)
|
||||
// So, we need to generate the hash ourself.
|
||||
const assetHashMap = {
|
||||
'app.js': {
|
||||
hash: await md5File(join(buildDir, dist, 'app.js'))
|
||||
hash: await md5File(join(dir, '.next', 'app.js'))
|
||||
}
|
||||
}
|
||||
const buildStatsPath = join(buildDir, dist, 'build-stats.json')
|
||||
const buildStatsPath = join(dir, '.next', 'build-stats.json')
|
||||
await fs.writeFile(buildStatsPath, JSON.stringify(assetHashMap), 'utf8')
|
||||
}
|
||||
|
||||
async function writeBuildId (buildDir, dir) {
|
||||
const dist = getConfig(dir).distDir
|
||||
const buildIdPath = join(buildDir, dist, 'BUILD_ID')
|
||||
async function writeBuildId (dir) {
|
||||
const buildIdPath = join(dir, '.next', 'BUILD_ID')
|
||||
const buildId = uuid.v4()
|
||||
await fs.writeFile(buildIdPath, buildId, 'utf8')
|
||||
}
|
||||
|
|
|
@ -4,10 +4,9 @@ import getConfig from '../config'
|
|||
|
||||
export default async function replaceCurrentBuild (dir, buildDir) {
|
||||
const dist = getConfig(dir).distDir
|
||||
const buildDist = getConfig(buildDir).distDir
|
||||
const _dir = join(dir, dist)
|
||||
const _buildDir = join(buildDir, dist)
|
||||
const oldDir = join(buildDir, `${buildDist}.old`)
|
||||
const _buildDir = join(buildDir, '.next')
|
||||
const oldDir = join(buildDir, '.next.old')
|
||||
|
||||
try {
|
||||
await move(_dir, oldDir)
|
||||
|
|
|
@ -37,7 +37,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
|
|||
const mainJS = dev
|
||||
? require.resolve('../../client/next-dev') : require.resolve('../../client/next')
|
||||
|
||||
let minChunks
|
||||
let totalPages
|
||||
|
||||
const entry = async () => {
|
||||
const entries = {
|
||||
|
@ -69,8 +69,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
|
|||
}
|
||||
}
|
||||
|
||||
// calculate minChunks of CommonsChunkPlugin for later use
|
||||
minChunks = Math.max(2, pages.filter((p) => p !== documentPage).length)
|
||||
totalPages = pages.filter((p) => p !== documentPage).length
|
||||
|
||||
return entries
|
||||
}
|
||||
|
@ -102,9 +101,8 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
|
|||
return module.context && module.context.indexOf('node_modules') >= 0
|
||||
}
|
||||
|
||||
// NOTE: it depends on the fact that the entry funtion is always called
|
||||
// before applying CommonsChunkPlugin
|
||||
return count >= minChunks
|
||||
// Move modules used in at-least 1/2 of the total pages into commons.
|
||||
return count >= totalPages * 0.5
|
||||
}
|
||||
}),
|
||||
// This chunk contains all the webpack related code. So, all the changes
|
||||
|
@ -268,10 +266,10 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
|
|||
context: dir,
|
||||
entry,
|
||||
output: {
|
||||
path: join(buildDir || dir, config.distDir),
|
||||
path: buildDir ? join(buildDir, '.next') : join(dir, config.distDir),
|
||||
filename: '[name]',
|
||||
libraryTarget: 'commonjs2',
|
||||
publicPath: '/_webpack/',
|
||||
publicPath: '/_next/webpack/',
|
||||
strictModuleExceptionHandling: true,
|
||||
devtoolModuleFilenameTemplate ({ resourcePath }) {
|
||||
const hash = createHash('sha1')
|
||||
|
|
|
@ -6,7 +6,8 @@ const cache = new Map()
|
|||
const defaultConfig = {
|
||||
webpack: null,
|
||||
poweredByHeader: true,
|
||||
distDir: '.next'
|
||||
distDir: '.next',
|
||||
assetPrefix: ''
|
||||
}
|
||||
|
||||
export default function getConfig (dir) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import React, { Component, PropTypes } from 'react'
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import htmlescape from 'htmlescape'
|
||||
import flush from 'styled-jsx/server'
|
||||
|
||||
|
@ -35,14 +36,14 @@ export class Head extends Component {
|
|||
|
||||
getChunkPreloadLink (filename) {
|
||||
const { __NEXT_DATA__ } = this.context._documentProps
|
||||
let { buildStats } = __NEXT_DATA__
|
||||
let { buildStats, assetPrefix } = __NEXT_DATA__
|
||||
const hash = buildStats ? buildStats[filename].hash : '-'
|
||||
|
||||
return (
|
||||
<link
|
||||
key={filename}
|
||||
rel='preload'
|
||||
href={`/_next/${hash}/${filename}`}
|
||||
href={`${assetPrefix}/_next/${hash}/${filename}`}
|
||||
as='script'
|
||||
/>
|
||||
)
|
||||
|
@ -65,12 +66,13 @@ export class Head extends Component {
|
|||
}
|
||||
|
||||
getPreloadDynamicChunks () {
|
||||
const { chunks } = this.context._documentProps
|
||||
const { chunks, __NEXT_DATA__ } = this.context._documentProps
|
||||
let { assetPrefix } = __NEXT_DATA__
|
||||
return chunks.map((chunk) => (
|
||||
<link
|
||||
key={chunk}
|
||||
rel='preload'
|
||||
href={`/_webpack/chunks/${chunk}`}
|
||||
href={`${assetPrefix}/_next/webpack/chunks/${chunk}`}
|
||||
as='script'
|
||||
/>
|
||||
))
|
||||
|
@ -78,11 +80,11 @@ export class Head extends Component {
|
|||
|
||||
render () {
|
||||
const { head, styles, __NEXT_DATA__ } = this.context._documentProps
|
||||
const { pathname, buildId } = __NEXT_DATA__
|
||||
const { pathname, buildId, assetPrefix } = __NEXT_DATA__
|
||||
|
||||
return <head>
|
||||
<link rel='preload' href={`/_next/${buildId}/page${pathname}`} as='script' />
|
||||
<link rel='preload' href={`/_next/${buildId}/page/_error`} as='script' />
|
||||
<link rel='preload' href={`${assetPrefix}/_next/${buildId}/page${pathname}`} as='script' />
|
||||
<link rel='preload' href={`${assetPrefix}/_next/${buildId}/page/_error`} as='script' />
|
||||
{this.getPreloadDynamicChunks()}
|
||||
{this.getPreloadMainLinks()}
|
||||
{(head || []).map((h, i) => React.cloneElement(h, { key: i }))}
|
||||
|
@ -115,13 +117,13 @@ export class NextScript extends Component {
|
|||
|
||||
getChunkScript (filename, additionalProps = {}) {
|
||||
const { __NEXT_DATA__ } = this.context._documentProps
|
||||
let { buildStats } = __NEXT_DATA__
|
||||
let { buildStats, assetPrefix } = __NEXT_DATA__
|
||||
const hash = buildStats ? buildStats[filename].hash : '-'
|
||||
|
||||
return (
|
||||
<script
|
||||
type='text/javascript'
|
||||
src={`/_next/${hash}/${filename}`}
|
||||
src={`${assetPrefix}/_next/${hash}/${filename}`}
|
||||
{...additionalProps}
|
||||
/>
|
||||
)
|
||||
|
@ -145,7 +147,8 @@ export class NextScript extends Component {
|
|||
}
|
||||
|
||||
getDynamicChunks () {
|
||||
const { chunks } = this.context._documentProps
|
||||
const { chunks, __NEXT_DATA__ } = this.context._documentProps
|
||||
let { assetPrefix } = __NEXT_DATA__
|
||||
return (
|
||||
<div>
|
||||
{chunks.map((chunk) => (
|
||||
|
@ -153,7 +156,7 @@ export class NextScript extends Component {
|
|||
async
|
||||
key={chunk}
|
||||
type='text/javascript'
|
||||
src={`/_webpack/chunks/${chunk}`}
|
||||
src={`${assetPrefix}/_next/webpack/chunks/${chunk}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
@ -162,7 +165,7 @@ export class NextScript extends Component {
|
|||
|
||||
render () {
|
||||
const { staticMarkup, __NEXT_DATA__, chunks } = this.context._documentProps
|
||||
const { pathname, buildId } = __NEXT_DATA__
|
||||
const { pathname, buildId, assetPrefix } = __NEXT_DATA__
|
||||
|
||||
__NEXT_DATA__.chunks = chunks
|
||||
|
||||
|
@ -183,8 +186,8 @@ export class NextScript extends Component {
|
|||
}
|
||||
`
|
||||
}} />}
|
||||
<script async type='text/javascript' src={`/_next/${buildId}/page${pathname}`} />
|
||||
<script async type='text/javascript' src={`/_next/${buildId}/page/_error`} />
|
||||
<script async type='text/javascript' src={`${assetPrefix}/_next/${buildId}/page${pathname}`} />
|
||||
<script async type='text/javascript' src={`${assetPrefix}/_next/${buildId}/page/_error`} />
|
||||
{staticMarkup ? null : this.getDynamicChunks()}
|
||||
{staticMarkup ? null : this.getScripts()}
|
||||
</div>
|
||||
|
|
|
@ -139,7 +139,7 @@ export default class HotReloader {
|
|||
} : {}
|
||||
|
||||
this.webpackDevMiddleware = webpackDevMiddleware(compiler, {
|
||||
publicPath: '/_webpack/',
|
||||
publicPath: '/_next/webpack/',
|
||||
noInfo: true,
|
||||
quiet: true,
|
||||
clientLogLevel: 'warning',
|
||||
|
@ -147,7 +147,10 @@ export default class HotReloader {
|
|||
...windowsSettings
|
||||
})
|
||||
|
||||
this.webpackHotMiddleware = webpackHotMiddleware(compiler, { log: false })
|
||||
this.webpackHotMiddleware = webpackHotMiddleware(compiler, {
|
||||
path: '/_next/webpack-hmr',
|
||||
log: false
|
||||
})
|
||||
this.onDemandEntries = onDemandEntryHandler(this.webpackDevMiddleware, compiler, {
|
||||
dir: this.dir,
|
||||
dev: true,
|
||||
|
|
|
@ -18,6 +18,11 @@ import getConfig from './config'
|
|||
// We need to go up one more level since we are in the `dist` directory
|
||||
import pkg from '../../package'
|
||||
|
||||
const internalPrefixes = [
|
||||
/^\/_next\//,
|
||||
/^\/static\//
|
||||
]
|
||||
|
||||
export default class Server {
|
||||
constructor ({ dir = '.', dev = false, staticMarkup = false, quiet = false } = {}) {
|
||||
this.dir = resolve(dir)
|
||||
|
@ -36,31 +41,34 @@ export default class Server {
|
|||
dir: this.dir,
|
||||
hotReloader: this.hotReloader,
|
||||
buildStats: this.buildStats,
|
||||
buildId: this.buildId
|
||||
buildId: this.buildId,
|
||||
assetPrefix: this.config.assetPrefix.replace(/\/$/, '')
|
||||
}
|
||||
|
||||
this.defineRoutes()
|
||||
}
|
||||
|
||||
getRequestHandler () {
|
||||
return (req, res, parsedUrl) => {
|
||||
// Parse url if parsedUrl not provided
|
||||
if (!parsedUrl) {
|
||||
parsedUrl = parseUrl(req.url, true)
|
||||
}
|
||||
|
||||
// Parse the querystring ourselves if the user doesn't handle querystring parsing
|
||||
if (typeof parsedUrl.query === 'string') {
|
||||
parsedUrl.query = parseQs(parsedUrl.query)
|
||||
}
|
||||
|
||||
return this.run(req, res, parsedUrl)
|
||||
.catch((err) => {
|
||||
if (!this.quiet) console.error(err)
|
||||
res.statusCode = 500
|
||||
res.end(STATUS_CODES[500])
|
||||
})
|
||||
handleRequest (req, res, parsedUrl) {
|
||||
// Parse url if parsedUrl not provided
|
||||
if (!parsedUrl) {
|
||||
parsedUrl = parseUrl(req.url, true)
|
||||
}
|
||||
|
||||
// Parse the querystring ourselves if the user doesn't handle querystring parsing
|
||||
if (typeof parsedUrl.query === 'string') {
|
||||
parsedUrl.query = parseQs(parsedUrl.query)
|
||||
}
|
||||
|
||||
return this.run(req, res, parsedUrl)
|
||||
.catch((err) => {
|
||||
if (!this.quiet) console.error(err)
|
||||
res.statusCode = 500
|
||||
res.end(STATUS_CODES[500])
|
||||
})
|
||||
}
|
||||
|
||||
getRequestHandler () {
|
||||
return this.handleRequest.bind(this)
|
||||
}
|
||||
|
||||
async prepare () {
|
||||
|
@ -92,7 +100,7 @@ export default class Server {
|
|||
},
|
||||
|
||||
// This is to support, webpack dynamic imports in production.
|
||||
'/_webpack/chunks/:name': async (req, res, params) => {
|
||||
'/_next/webpack/chunks/:name': async (req, res, params) => {
|
||||
res.setHeader('Cache-Control', 'max-age=365000000, immutable')
|
||||
const p = join(this.dir, '.next', 'chunks', params.name)
|
||||
await this.serveStatic(req, res, p)
|
||||
|
@ -215,12 +223,16 @@ export default class Server {
|
|||
}
|
||||
}
|
||||
|
||||
async render (req, res, pathname, query) {
|
||||
async render (req, res, pathname, query, parsedUrl) {
|
||||
if (this.isInternalUrl(req)) {
|
||||
return this.handleRequest(req, res, parsedUrl)
|
||||
}
|
||||
|
||||
if (this.config.poweredByHeader) {
|
||||
res.setHeader('X-Powered-By', `Next.js ${pkg.version}`)
|
||||
}
|
||||
const html = await this.renderToHTML(req, res, pathname, query)
|
||||
return sendHTML(res, html, req.method)
|
||||
return sendHTML(req, res, html, req.method)
|
||||
}
|
||||
|
||||
async renderToHTML (req, res, pathname, query) {
|
||||
|
@ -248,7 +260,7 @@ export default class Server {
|
|||
|
||||
async renderError (err, req, res, pathname, query) {
|
||||
const html = await this.renderErrorToHTML(err, req, res, pathname, query)
|
||||
return sendHTML(res, html, req.method)
|
||||
return sendHTML(req, res, html, req.method)
|
||||
}
|
||||
|
||||
async renderErrorToHTML (err, req, res, pathname, query) {
|
||||
|
@ -291,6 +303,16 @@ export default class Server {
|
|||
}
|
||||
}
|
||||
|
||||
isInternalUrl (req) {
|
||||
for (const prefix of internalPrefixes) {
|
||||
if (prefix.test(req.url)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
readBuildId () {
|
||||
const buildIdPath = join(this.dir, this.dist, 'BUILD_ID')
|
||||
const buildId = fs.readFileSync(buildIdPath, 'utf8')
|
||||
|
|
|
@ -2,6 +2,8 @@ import { join } from 'path'
|
|||
import { createElement } from 'react'
|
||||
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
||||
import send from 'send'
|
||||
import generateETag from 'etag'
|
||||
import fresh from 'fresh'
|
||||
import requireModule from './require'
|
||||
import getConfig from './config'
|
||||
import resolvePath from './resolve'
|
||||
|
@ -14,7 +16,7 @@ import { flushChunks } from '../lib/dynamic'
|
|||
|
||||
export async function render (req, res, pathname, query, opts) {
|
||||
const html = await renderToHTML(req, res, pathname, opts)
|
||||
sendHTML(res, html, req.method)
|
||||
sendHTML(req, res, html, req.method)
|
||||
}
|
||||
|
||||
export function renderToHTML (req, res, pathname, query, opts) {
|
||||
|
@ -23,7 +25,7 @@ export function renderToHTML (req, res, pathname, query, opts) {
|
|||
|
||||
export async function renderError (err, req, res, pathname, query, opts) {
|
||||
const html = await renderErrorToHTML(err, req, res, query, opts)
|
||||
sendHTML(res, html, req.method)
|
||||
sendHTML(req, res, html, req.method)
|
||||
}
|
||||
|
||||
export function renderErrorToHTML (err, req, res, pathname, query, opts = {}) {
|
||||
|
@ -36,6 +38,7 @@ async function doRender (req, res, pathname, query, {
|
|||
buildId,
|
||||
buildStats,
|
||||
hotReloader,
|
||||
assetPrefix,
|
||||
dir = process.cwd(),
|
||||
dev = false,
|
||||
staticMarkup = false
|
||||
|
@ -95,6 +98,7 @@ async function doRender (req, res, pathname, query, {
|
|||
query,
|
||||
buildId,
|
||||
buildStats,
|
||||
assetPrefix,
|
||||
err: (err && dev) ? errorToJSON(err) : null
|
||||
},
|
||||
dev,
|
||||
|
@ -148,9 +152,17 @@ export async function renderScriptError (req, res, page, error, customFields, op
|
|||
`)
|
||||
}
|
||||
|
||||
export function sendHTML (res, html, method) {
|
||||
export function sendHTML (req, res, html, method) {
|
||||
if (res.finished) return
|
||||
const etag = generateETag(html)
|
||||
|
||||
if (fresh(req.headers, { etag })) {
|
||||
res.statusCode = 304
|
||||
res.end()
|
||||
return
|
||||
}
|
||||
|
||||
res.setHeader('ETag', etag)
|
||||
res.setHeader('Content-Type', 'text/html')
|
||||
res.setHeader('Content-Length', Buffer.byteLength(html))
|
||||
res.end(method === 'HEAD' ? null : html)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/* global describe, test, expect */
|
||||
import fetch from 'node-fetch'
|
||||
|
||||
export default function (context) {
|
||||
describe('Misc', () => {
|
||||
|
@ -12,5 +13,14 @@ export default function (context) {
|
|||
const html = await context.app.renderToHTML({}, res, '/finish-response', {})
|
||||
expect(html).toBeFalsy()
|
||||
})
|
||||
|
||||
test('allow etag header support', async () => {
|
||||
const url = `http://localhost:${context.appPort}/stateless`
|
||||
const etag = (await fetch(url)).headers.get('ETag')
|
||||
|
||||
const headers = { 'If-None-Match': etag }
|
||||
const res2 = await fetch(url, { headers })
|
||||
expect(res2.status).toBe(304)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import { pkg } from 'next-test-utils'
|
|||
export default function ({ app }) {
|
||||
describe('X-Powered-By header', () => {
|
||||
test('set it by default', async () => {
|
||||
const req = { url: '/stateless' }
|
||||
const req = { url: '/stateless', headers: {} }
|
||||
const headers = {}
|
||||
const res = {
|
||||
setHeader (key, value) {
|
||||
|
@ -18,7 +18,7 @@ export default function ({ app }) {
|
|||
})
|
||||
|
||||
test('do not set it when poweredByHeader==false', async () => {
|
||||
const req = { url: '/stateless' }
|
||||
const req = { url: '/stateless', headers: {} }
|
||||
const originalConfigValue = app.config.poweredByHeader
|
||||
app.config.poweredByHeader = false
|
||||
const res = {
|
||||
|
|
195
yarn.lock
195
yarn.lock
|
@ -289,15 +289,14 @@ babel-core@6.24.0, babel-core@^6.0.0, babel-core@^6.24.0, babel-core@^6.3.0:
|
|||
slash "^1.0.0"
|
||||
source-map "^0.5.0"
|
||||
|
||||
babel-eslint@7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.0.tgz#8941514b9dead06f0df71b29d5d5b193a92ee0ae"
|
||||
babel-eslint@7.2.2:
|
||||
version "7.2.2"
|
||||
resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.2.tgz#0da2cbe6554fd0fb069f19674f2db2f9c59270ff"
|
||||
dependencies:
|
||||
babel-code-frame "^6.22.0"
|
||||
babel-traverse "^6.23.1"
|
||||
babel-types "^6.23.0"
|
||||
babylon "^6.16.1"
|
||||
lodash "^4.17.4"
|
||||
|
||||
babel-generator@6.24.0, babel-generator@^6.18.0, babel-generator@^6.24.0:
|
||||
version "6.24.0"
|
||||
|
@ -504,7 +503,7 @@ babel-plugin-syntax-class-properties@^6.8.0:
|
|||
version "6.13.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
|
||||
|
||||
babel-plugin-syntax-dynamic-import@^6.18.0:
|
||||
babel-plugin-syntax-dynamic-import@6.18.0:
|
||||
version "6.18.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da"
|
||||
|
||||
|
@ -557,7 +556,7 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
|
|||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-block-scoping@^6.22.0:
|
||||
babel-plugin-transform-es2015-block-scoping@^6.22.0, babel-plugin-transform-es2015-block-scoping@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz#e48895cf0b375be148cd7c8879b422707a053b51"
|
||||
dependencies:
|
||||
|
@ -567,7 +566,7 @@ babel-plugin-transform-es2015-block-scoping@^6.22.0:
|
|||
babel-types "^6.23.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-plugin-transform-es2015-classes@^6.22.0:
|
||||
babel-plugin-transform-es2015-classes@^6.22.0, babel-plugin-transform-es2015-classes@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz#49b53f326202a2fd1b3bbaa5e2edd8a4f78643c1"
|
||||
dependencies:
|
||||
|
@ -588,7 +587,7 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0:
|
|||
babel-runtime "^6.22.0"
|
||||
babel-template "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-destructuring@^6.22.0:
|
||||
babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
|
||||
dependencies:
|
||||
|
@ -601,7 +600,7 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0:
|
|||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-for-of@^6.22.0:
|
||||
babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
|
||||
dependencies:
|
||||
|
@ -621,7 +620,7 @@ babel-plugin-transform-es2015-literals@^6.22.0:
|
|||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-modules-amd@^6.24.0:
|
||||
babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.0:
|
||||
version "6.24.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz#a1911fb9b7ec7e05a43a63c5995007557bcf6a2e"
|
||||
dependencies:
|
||||
|
@ -629,7 +628,7 @@ babel-plugin-transform-es2015-modules-amd@^6.24.0:
|
|||
babel-runtime "^6.22.0"
|
||||
babel-template "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-modules-commonjs@6.24.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.0:
|
||||
babel-plugin-transform-es2015-modules-commonjs@6.24.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.0:
|
||||
version "6.24.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz#e921aefb72c2cc26cb03d107626156413222134f"
|
||||
dependencies:
|
||||
|
@ -638,7 +637,7 @@ babel-plugin-transform-es2015-modules-commonjs@6.24.0, babel-plugin-transform-es
|
|||
babel-template "^6.23.0"
|
||||
babel-types "^6.23.0"
|
||||
|
||||
babel-plugin-transform-es2015-modules-systemjs@^6.22.0:
|
||||
babel-plugin-transform-es2015-modules-systemjs@^6.22.0, babel-plugin-transform-es2015-modules-systemjs@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz#ae3469227ffac39b0310d90fec73bfdc4f6317b0"
|
||||
dependencies:
|
||||
|
@ -646,7 +645,7 @@ babel-plugin-transform-es2015-modules-systemjs@^6.22.0:
|
|||
babel-runtime "^6.22.0"
|
||||
babel-template "^6.23.0"
|
||||
|
||||
babel-plugin-transform-es2015-modules-umd@^6.24.0:
|
||||
babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.0:
|
||||
version "6.24.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz#fd5fa63521cae8d273927c3958afd7c067733450"
|
||||
dependencies:
|
||||
|
@ -661,7 +660,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0:
|
|||
babel-helper-replace-supers "^6.22.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-parameters@^6.22.0:
|
||||
babel-plugin-transform-es2015-parameters@^6.22.0, babel-plugin-transform-es2015-parameters@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b"
|
||||
dependencies:
|
||||
|
@ -699,7 +698,7 @@ babel-plugin-transform-es2015-template-literals@^6.22.0:
|
|||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-es2015-typeof-symbol@^6.22.0:
|
||||
babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
|
||||
dependencies:
|
||||
|
@ -763,9 +762,9 @@ babel-plugin-transform-react-jsx@^6.23.0:
|
|||
babel-plugin-syntax-jsx "^6.8.0"
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-react-remove-prop-types@0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.npmjs.org/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.3.2.tgz#6da8d834c6d7ad8ab02f956509790cfaa01ffe19"
|
||||
babel-plugin-transform-react-remove-prop-types@0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.0.tgz#f63840e7953563d661be8c647b094d74d7363f17"
|
||||
|
||||
babel-plugin-transform-regenerator@^6.22.0:
|
||||
version "6.22.0"
|
||||
|
@ -790,7 +789,41 @@ babel-plugin-transform-strict-mode@^6.22.0:
|
|||
babel-runtime "^6.22.0"
|
||||
babel-types "^6.22.0"
|
||||
|
||||
babel-preset-es2015@6.24.0, babel-preset-es2015@^6.24.0:
|
||||
babel-preset-env@1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.3.3.tgz#5913407784e3d98de2aa814a3ef9059722b34e0b"
|
||||
dependencies:
|
||||
babel-plugin-check-es2015-constants "^6.22.0"
|
||||
babel-plugin-syntax-trailing-function-commas "^6.22.0"
|
||||
babel-plugin-transform-async-to-generator "^6.22.0"
|
||||
babel-plugin-transform-es2015-arrow-functions "^6.22.0"
|
||||
babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
|
||||
babel-plugin-transform-es2015-block-scoping "^6.23.0"
|
||||
babel-plugin-transform-es2015-classes "^6.23.0"
|
||||
babel-plugin-transform-es2015-computed-properties "^6.22.0"
|
||||
babel-plugin-transform-es2015-destructuring "^6.23.0"
|
||||
babel-plugin-transform-es2015-duplicate-keys "^6.22.0"
|
||||
babel-plugin-transform-es2015-for-of "^6.23.0"
|
||||
babel-plugin-transform-es2015-function-name "^6.22.0"
|
||||
babel-plugin-transform-es2015-literals "^6.22.0"
|
||||
babel-plugin-transform-es2015-modules-amd "^6.22.0"
|
||||
babel-plugin-transform-es2015-modules-commonjs "^6.23.0"
|
||||
babel-plugin-transform-es2015-modules-systemjs "^6.23.0"
|
||||
babel-plugin-transform-es2015-modules-umd "^6.23.0"
|
||||
babel-plugin-transform-es2015-object-super "^6.22.0"
|
||||
babel-plugin-transform-es2015-parameters "^6.23.0"
|
||||
babel-plugin-transform-es2015-shorthand-properties "^6.22.0"
|
||||
babel-plugin-transform-es2015-spread "^6.22.0"
|
||||
babel-plugin-transform-es2015-sticky-regex "^6.22.0"
|
||||
babel-plugin-transform-es2015-template-literals "^6.22.0"
|
||||
babel-plugin-transform-es2015-typeof-symbol "^6.23.0"
|
||||
babel-plugin-transform-es2015-unicode-regex "^6.22.0"
|
||||
babel-plugin-transform-exponentiation-operator "^6.22.0"
|
||||
babel-plugin-transform-regenerator "^6.22.0"
|
||||
browserslist "^1.4.0"
|
||||
invariant "^2.2.2"
|
||||
|
||||
babel-preset-es2015@6.24.0:
|
||||
version "6.24.0"
|
||||
resolved "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.0.tgz#c162d68b1932696e036cd3110dc1ccd303d2673a"
|
||||
dependencies:
|
||||
|
@ -819,19 +852,6 @@ babel-preset-es2015@6.24.0, babel-preset-es2015@^6.24.0:
|
|||
babel-plugin-transform-es2015-unicode-regex "^6.22.0"
|
||||
babel-plugin-transform-regenerator "^6.22.0"
|
||||
|
||||
babel-preset-es2016@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.npmjs.org/babel-preset-es2016/-/babel-preset-es2016-6.22.0.tgz#b061aaa3983d40c9fbacfa3743b5df37f336156c"
|
||||
dependencies:
|
||||
babel-plugin-transform-exponentiation-operator "^6.22.0"
|
||||
|
||||
babel-preset-es2017@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "https://registry.npmjs.org/babel-preset-es2017/-/babel-preset-es2017-6.22.0.tgz#de2f9da5a30c50d293fb54a0ba15d6ddc573f0f2"
|
||||
dependencies:
|
||||
babel-plugin-syntax-trailing-function-commas "^6.22.0"
|
||||
babel-plugin-transform-async-to-generator "^6.22.0"
|
||||
|
||||
babel-preset-flow@^6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d"
|
||||
|
@ -850,14 +870,6 @@ babel-preset-jest@^19.0.0:
|
|||
dependencies:
|
||||
babel-plugin-jest-hoist "^19.0.0"
|
||||
|
||||
babel-preset-latest@6.24.0:
|
||||
version "6.24.0"
|
||||
resolved "https://registry.npmjs.org/babel-preset-latest/-/babel-preset-latest-6.24.0.tgz#a68d20f509edcc5d7433a48dfaebf7e4f2cd4cb7"
|
||||
dependencies:
|
||||
babel-preset-es2015 "^6.24.0"
|
||||
babel-preset-es2016 "^6.22.0"
|
||||
babel-preset-es2017 "^6.22.0"
|
||||
|
||||
babel-preset-react@6.23.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.23.0.tgz#eb7cee4de98a3f94502c28565332da9819455195"
|
||||
|
@ -888,6 +900,16 @@ babel-runtime@6.23.0, babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtim
|
|||
core-js "^2.4.0"
|
||||
regenerator-runtime "^0.10.0"
|
||||
|
||||
babel-template@6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-traverse "^6.24.1"
|
||||
babel-types "^6.24.1"
|
||||
babylon "^6.11.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0, babel-template@^6.7.0:
|
||||
version "6.23.0"
|
||||
resolved "https://registry.npmjs.org/babel-template/-/babel-template-6.23.0.tgz#04d4f270adbb3aa704a8143ae26faa529238e638"
|
||||
|
@ -898,16 +920,6 @@ babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0, babel-te
|
|||
babylon "^6.11.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-template@^6.24.1:
|
||||
version "6.24.1"
|
||||
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333"
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
babel-traverse "^6.24.1"
|
||||
babel-types "^6.24.1"
|
||||
babylon "^6.11.0"
|
||||
lodash "^4.2.0"
|
||||
|
||||
babel-traverse@6.21.0:
|
||||
version "6.21.0"
|
||||
resolved "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.21.0.tgz#69c6365804f1a4f69eb1213f85b00a818b8c21ad"
|
||||
|
@ -1111,6 +1123,13 @@ browserify-zlib@^0.1.4:
|
|||
dependencies:
|
||||
pako "~0.2.0"
|
||||
|
||||
browserslist@^1.4.0:
|
||||
version "1.7.7"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9"
|
||||
dependencies:
|
||||
caniuse-db "^1.0.30000639"
|
||||
electron-to-chromium "^1.2.7"
|
||||
|
||||
bser@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/bser/-/bser-1.0.2.tgz#381116970b2a6deea5646dd15dd7278444b56169"
|
||||
|
@ -1181,6 +1200,10 @@ camelcase@^3.0.0:
|
|||
version "3.0.0"
|
||||
resolved "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a"
|
||||
|
||||
caniuse-db@^1.0.30000639:
|
||||
version "1.0.30000650"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000650.tgz#615f564d367533d32b82d72ada09661e75386bab"
|
||||
|
||||
case-sensitive-paths-webpack-plugin@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.0.0.tgz#60142d7d0beabdb35676ef0aeace3027da0578ba"
|
||||
|
@ -1242,9 +1265,9 @@ chokidar@^1.4.3, chokidar@^1.6.1:
|
|||
optionalDependencies:
|
||||
fsevents "^1.0.0"
|
||||
|
||||
chromedriver@2.28.0:
|
||||
version "2.28.0"
|
||||
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.28.0.tgz#ea0c383621dd27db340c612b85fe39414c16ec79"
|
||||
chromedriver@2.29.0:
|
||||
version "2.29.0"
|
||||
resolved "https://registry.npmjs.org/chromedriver/-/chromedriver-2.29.0.tgz#e3fd8b3c08dce2562b80ef1b0b846597659d0cc3"
|
||||
dependencies:
|
||||
adm-zip "^0.4.7"
|
||||
kew "^0.7.0"
|
||||
|
@ -1703,6 +1726,10 @@ ee-first@1.1.1:
|
|||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
|
||||
electron-to-chromium@^1.2.7:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.3.tgz#651eb63fe89f39db70ffc8dbd5d9b66958bc6a0e"
|
||||
|
||||
elegant-spinner@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
|
||||
|
@ -1981,7 +2008,7 @@ esutils@^2.0.0, esutils@^2.0.2:
|
|||
version "2.0.2"
|
||||
resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||
|
||||
etag@~1.8.0:
|
||||
etag@1.8.0, etag@~1.8.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051"
|
||||
|
||||
|
@ -2066,9 +2093,9 @@ fb-watchman@^2.0.0:
|
|||
dependencies:
|
||||
bser "^2.0.0"
|
||||
|
||||
fbjs@^0.8.1, fbjs@^0.8.4:
|
||||
version "0.8.9"
|
||||
resolved "https://registry.npmjs.org/fbjs/-/fbjs-0.8.9.tgz#180247fbd347dcc9004517b904f865400a0c8f14"
|
||||
fbjs@^0.8.9:
|
||||
version "0.8.12"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.12.tgz#10b5d92f76d45575fd63a217d4ea02bea2f8ed04"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
|
@ -2340,17 +2367,7 @@ glob-promise@3.1.0:
|
|||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/glob-promise/-/glob-promise-3.1.0.tgz#198882a3817be7dc2c55f92623aa9e7b3f82d1eb"
|
||||
|
||||
glob@^6.0.1:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
||||
dependencies:
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "2 || 3"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1:
|
||||
glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
|
||||
dependencies:
|
||||
|
@ -2361,6 +2378,16 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1:
|
|||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^6.0.1:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
||||
dependencies:
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "2 || 3"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
global@^4.3.0:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.npmjs.org/global/-/global-4.3.1.tgz#5f757908c7cbabce54f386ae440e11e26b7916df"
|
||||
|
@ -2613,7 +2640,7 @@ interpret@^1.0.0:
|
|||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c"
|
||||
|
||||
invariant@^2.2.0:
|
||||
invariant@^2.2.0, invariant@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||
dependencies:
|
||||
|
@ -4042,6 +4069,18 @@ promise@^7.1.1:
|
|||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@15.5.7:
|
||||
version "15.5.7"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.7.tgz#231c4f29cdd82e355011d4889386ca9059544dd1"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
|
||||
prop-types@^15.5.2, prop-types@~15.5.0:
|
||||
version "15.5.6"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.6.tgz#797a915b1714b645ebb7c5d6cc690346205bd2aa"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
|
||||
prr@~0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a"
|
||||
|
@ -4112,13 +4151,14 @@ react-deep-force-update@^2.0.1:
|
|||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/react-deep-force-update/-/react-deep-force-update-2.0.1.tgz#4f7f6c12c3e7de42f345992a3c518236fa1ecad3"
|
||||
|
||||
react-dom@15.4.2:
|
||||
version "15.4.2"
|
||||
resolved "https://registry.npmjs.org/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f"
|
||||
react-dom@15.5.3:
|
||||
version "15.5.3"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.5.3.tgz#2ee127ce942df55da53111ae303316e68072b5c5"
|
||||
dependencies:
|
||||
fbjs "^0.8.1"
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "~15.5.0"
|
||||
|
||||
react-hot-loader@3.0.0-beta.6:
|
||||
version "3.0.0-beta.6"
|
||||
|
@ -4137,13 +4177,14 @@ react-proxy@^3.0.0-alpha.0:
|
|||
dependencies:
|
||||
lodash "^4.6.1"
|
||||
|
||||
react@15.4.2:
|
||||
version "15.4.2"
|
||||
resolved "https://registry.npmjs.org/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef"
|
||||
react@15.5.3:
|
||||
version "15.5.3"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-15.5.3.tgz#84055382c025dec4e3b902bb61a8697cc79c1258"
|
||||
dependencies:
|
||||
fbjs "^0.8.4"
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.2"
|
||||
|
||||
read-pkg-up@^1.0.1:
|
||||
version "1.0.1"
|
||||
|
|
Loading…
Reference in a new issue