diff --git a/asset.js b/asset.js new file mode 100644 index 00000000..fd0bd5db --- /dev/null +++ b/asset.js @@ -0,0 +1 @@ +module.exports = require('./dist/lib/asset') diff --git a/bin/next-dev b/bin/next-dev index bfdfc29c..edf2255b 100755 --- a/bin/next-dev +++ b/bin/next-dev @@ -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: { @@ -64,7 +62,7 @@ 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('pkg-up').sync('.') 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 \`.` diff --git a/client/index.js b/client/index.js index 0283d981..78d953e5 100644 --- a/client/index.js +++ b/client/index.js @@ -6,6 +6,7 @@ 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' // Polyfill Promise globally // This is needed because Webpack2's dynamic loading(common chunks) code @@ -29,6 +30,9 @@ const { location } = window +// With this, static assets will work across zones +asset.setAssetPrefix(assetPrefix) + const asPath = getURL() const pageLoader = new PageLoader(buildId, assetPrefix) @@ -93,10 +97,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 } @@ -159,7 +160,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 { diff --git a/client/next-dev.js b/client/next-dev.js index ef771c32..7f5e13e0 100644 --- a/client/next-dev.js +++ b/client/next-dev.js @@ -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 }) diff --git a/client/on-demand-entries-client.js b/client/on-demand-entries-client.js index 8b5588d5..65ed2c29 100644 --- a/client/on-demand-entries-client.js +++ b/client/on-demand-entries-client.js @@ -3,6 +3,12 @@ import Router from '../lib/router' import fetch from 'unfetch' +const { + __NEXT_DATA__: { + assetPrefix + } +} = window + export default () => { Router.ready(() => { Router.router.events.on('routeChangeComplete', ping) @@ -10,16 +16,16 @@ export default () => { 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() diff --git a/client/webpack-hot-middleware-client.js b/client/webpack-hot-middleware-client.js index 10dbf28d..24477fe5 100644 --- a/client/webpack-hot-middleware-client.js +++ b/client/webpack-hot-middleware-client.js @@ -1,7 +1,19 @@ -import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?overlay=false&reload=true&path=/_next/webpack-hmr' +import webpackHotMiddlewareClient from 'webpack-hot-middleware/client?autoConnect=false' import Router from '../lib/router' +const { + __NEXT_DATA__: { + assetPrefix + } +} = window + export default () => { + webpackHotMiddlewareClient.setOptionsAndConnect({ + overlay: false, + reload: true, + path: `${assetPrefix}/_next/webpack-hmr` + }) + const handlers = { reload (route) { if (route === '/_error') { diff --git a/css.js b/css.js deleted file mode 100644 index e4d6d15f..00000000 --- a/css.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./dist/lib/css') diff --git a/errors/powered-by-header-option-removed.md b/errors/powered-by-header-option-removed.md new file mode 100644 index 00000000..216fbda8 --- /dev/null +++ b/errors/powered-by-header-option-removed.md @@ -0,0 +1,15 @@ +# The poweredByHeader has been removed + +#### Why This Error Occurred + +Starting at Next.js version 5.0.0 the `poweredByHeader` option has been removed. + +#### Possible Ways to Fix It + +If you still want to remove `x-powered-by` you can use one of the custom-server examples. + +And then manually remove the header using `res.removeHeader('x-powered-by')` + +### Useful Links + +- [Custom Server documentation + examples](https://github.com/zeit/next.js#custom-server-and-routing) diff --git a/examples/hello-world/pages/about2.js b/examples/hello-world/pages/about2.js new file mode 100644 index 00000000..44ce6571 --- /dev/null +++ b/examples/hello-world/pages/about2.js @@ -0,0 +1,3 @@ +export default () => ( +
About 2
+) diff --git a/examples/hello-world/pages/day/index.js b/examples/hello-world/pages/day/index.js new file mode 100644 index 00000000..5a581008 --- /dev/null +++ b/examples/hello-world/pages/day/index.js @@ -0,0 +1,3 @@ +export default () => ( +
Hello Day
+) diff --git a/examples/with-zones/README.md b/examples/with-zones/README.md new file mode 100644 index 00000000..5349c814 --- /dev/null +++ b/examples/with-zones/README.md @@ -0,0 +1,71 @@ +[![Deploy to now](https://deploy.now.sh/static/button.svg)](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-zones) + +# Using multiple zones + +With Next.js you can use multiple apps as a single app using it's multi-zones feature. +This is an example showing how to use it. + +In this example, we've two apps: 'home' and 'blog'. +We also have a set of rules defined in `rules.json` for the proxy. + +Now let's start two of our app using: + +``` +npm run home +npm run blog +``` + +Then start the proxy: + +``` +npm run proxy +``` + +Now you can visit http://localhost:9000 and access and develop both apps a single app. + +### Proxy Rules + +This is the place we define rules for our proxy. Here are the rules(in `rules.json`) available for this app: + +```json +{ + "rules": [ + {"pathname": "/blog", "method":["GET", "POST", "OPTIONS"], "dest": "http://localhost:5000"}, + {"pathname": "/**", "dest": "http://localhost:4000"} + ] +} +``` + +These rules are based on ZEIT now [path alias](https://zeit.co/docs/features/path-aliases) rules and use [`micro-proxy`](https://github.com/zeit/micro-proxy) as the proxy. + +## Special Notes + +* All pages should be unique across zones. A page with the same name should not exist in multiple zones. Otherwise, there'll be unexpected behaviour in client side navigation. + * According to the above example, a page named `blog` should not be exist in the `home` zone. + +## Production Deployment + +Here's how are going to deploy this application into production. + +* Open the `now.json` file in both `blog` and `home` directories and change the aliases as you wish. +* Then update `rules-prod.json` accordingly. +* Now deploy both apps: + +~~~sh +cd home +now && now alias +cd ../blog +now && now alias +cd .. +~~~ + +* Finally, set the path alias rules with + +~~~sh +now alias with-zones.now.sh -r rules-prod.json +~~~ + +> You can use a domain name of your choice in the above command instead of `with-zones.now.sh`. + +That's it. +Now you can access the final app via: diff --git a/examples/with-zones/blog/.gitignore b/examples/with-zones/blog/.gitignore new file mode 100644 index 00000000..f74c7818 --- /dev/null +++ b/examples/with-zones/blog/.gitignore @@ -0,0 +1,2 @@ +.next +node_modules diff --git a/examples/with-zones/blog/next.config.js b/examples/with-zones/blog/next.config.js new file mode 100644 index 00000000..d930ee9c --- /dev/null +++ b/examples/with-zones/blog/next.config.js @@ -0,0 +1,6 @@ +const { NOW_URL } = process.env +const { alias } = require('./now.json') + +module.exports = { + assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:5000' +} diff --git a/examples/with-zones/blog/now.json b/examples/with-zones/blog/now.json new file mode 100644 index 00000000..f5759035 --- /dev/null +++ b/examples/with-zones/blog/now.json @@ -0,0 +1,3 @@ +{ + "alias": "with-zones-blog.now.sh" +} diff --git a/examples/with-zones/blog/package.json b/examples/with-zones/blog/package.json new file mode 100644 index 00000000..cc274c2f --- /dev/null +++ b/examples/with-zones/blog/package.json @@ -0,0 +1,14 @@ +{ + "name": "with-zones-blog", + "version": "1.0.0", + "scripts": { + "build": "next build", + "start": "next start -p 4000" + }, + "dependencies": { + "next": "zones", + "react": "^16.0.0", + "react-dom": "^16.0.0" + }, + "license": "ISC" +} diff --git a/examples/with-zones/blog/pages/blog.js b/examples/with-zones/blog/pages/blog.js new file mode 100644 index 00000000..1f866126 --- /dev/null +++ b/examples/with-zones/blog/pages/blog.js @@ -0,0 +1,5 @@ +export default () => ( +
+ This is our blog +
+) diff --git a/examples/with-zones/home/.gitignore b/examples/with-zones/home/.gitignore new file mode 100644 index 00000000..f74c7818 --- /dev/null +++ b/examples/with-zones/home/.gitignore @@ -0,0 +1,2 @@ +.next +node_modules diff --git a/examples/with-zones/home/components/Header.js b/examples/with-zones/home/components/Header.js new file mode 100644 index 00000000..b631afc8 --- /dev/null +++ b/examples/with-zones/home/components/Header.js @@ -0,0 +1,5 @@ +export default () => ( +
+

The Company

+
+) diff --git a/examples/with-zones/home/next.config.js b/examples/with-zones/home/next.config.js new file mode 100644 index 00000000..e76728e6 --- /dev/null +++ b/examples/with-zones/home/next.config.js @@ -0,0 +1,6 @@ +const { NOW_URL } = process.env +const { alias } = require('./now.json') + +module.exports = { + assetPrefix: NOW_URL ? `https://${alias}` : 'http://localhost:4000' +} diff --git a/examples/with-zones/home/now.json b/examples/with-zones/home/now.json new file mode 100644 index 00000000..f519fe4c --- /dev/null +++ b/examples/with-zones/home/now.json @@ -0,0 +1,3 @@ +{ + "alias": "with-zones-home.now.sh" +} diff --git a/examples/with-zones/home/package.json b/examples/with-zones/home/package.json new file mode 100644 index 00000000..f534c02a --- /dev/null +++ b/examples/with-zones/home/package.json @@ -0,0 +1,14 @@ +{ + "name": "with-zones-home", + "version": "1.0.0", + "scripts": { + "build": "next build", + "start": "next start -p 4000" + }, + "dependencies": { + "next": "zones", + "react": "^16.0.0", + "react-dom": "^16.0.0" + }, + "license": "ISC" +} diff --git a/examples/with-zones/home/pages/about.js b/examples/with-zones/home/pages/about.js new file mode 100644 index 00000000..79cbefd0 --- /dev/null +++ b/examples/with-zones/home/pages/about.js @@ -0,0 +1,10 @@ +import asset from 'next/asset' +import Link from 'next/link' + +export default () => ( +
+

This is the about page.

+
Go Back
+ +
+) diff --git a/examples/with-zones/home/pages/index.js b/examples/with-zones/home/pages/index.js new file mode 100644 index 00000000..c251da2e --- /dev/null +++ b/examples/with-zones/home/pages/index.js @@ -0,0 +1,15 @@ +import Link from 'next/link' +import asset from 'next/asset' +import dynamic from 'next/dynamic' + +const Header = dynamic(import('../components/Header')) + +export default () => ( +
+
+

This is our homepage

+
Blog
+
About us
+ +
+) diff --git a/examples/with-zones/home/static/nextjs.png b/examples/with-zones/home/static/nextjs.png new file mode 100644 index 00000000..98cbbf09 Binary files /dev/null and b/examples/with-zones/home/static/nextjs.png differ diff --git a/examples/with-zones/home/static/zeit.png b/examples/with-zones/home/static/zeit.png new file mode 100644 index 00000000..8b80fabb Binary files /dev/null and b/examples/with-zones/home/static/zeit.png differ diff --git a/examples/with-zones/package.json b/examples/with-zones/package.json new file mode 100644 index 00000000..3269a598 --- /dev/null +++ b/examples/with-zones/package.json @@ -0,0 +1,20 @@ +{ + "name": "with-zones", + "version": "1.0.0", + "scripts": { + "home": "next home -p 4000", + "home-build": "next build home", + "home-start": "next start home -p 4000", + "blog": "next blog -p 5000", + "blog-build": "next build blog", + "blog-start": "next start blog -p 5000", + "proxy": "micro-proxy -r rules-dev.json" + }, + "dependencies": { + "micro-proxy": "^1.0.0", + "next": "latest", + "react": "^16.0.0", + "react-dom": "^16.0.0" + }, + "license": "ISC" +} diff --git a/examples/with-zones/rules-dev.json b/examples/with-zones/rules-dev.json new file mode 100644 index 00000000..680a3302 --- /dev/null +++ b/examples/with-zones/rules-dev.json @@ -0,0 +1,6 @@ +{ + "rules": [ + {"pathname": "/blog", "method":["GET", "POST", "OPTIONS"], "dest": "http://localhost:5000"}, + {"pathname": "/**", "dest": "http://localhost:4000"} + ] +} diff --git a/examples/with-zones/rules-prod.json b/examples/with-zones/rules-prod.json new file mode 100644 index 00000000..aa8f6da6 --- /dev/null +++ b/examples/with-zones/rules-prod.json @@ -0,0 +1,6 @@ +{ + "rules": [ + {"pathname": "/blog", "method":["GET", "POST", "OPTIONS"], "dest": "https://with-zones-blog.now.sh"}, + {"pathname": "/**", "dest": "https://with-zones-home.now.sh"} + ] +} diff --git a/lib/asset.js b/lib/asset.js new file mode 100644 index 00000000..f9dfe50c --- /dev/null +++ b/lib/asset.js @@ -0,0 +1,10 @@ +let assetPrefix + +export default function asset (path) { + const pathWithoutSlash = path.replace(/^\//, '') + return `${assetPrefix}/static/${pathWithoutSlash}` +} + +export function setAssetPrefix (url) { + assetPrefix = url +} diff --git a/lib/css.js b/lib/css.js deleted file mode 100644 index b87b3886..00000000 --- a/lib/css.js +++ /dev/null @@ -1 +0,0 @@ -throw new Error(`'next/css' has been removed in Next.js 2.0. Please refer to the migration guide: https://github.com/zeit/next.js/wiki/Migrating-from-next-css`) diff --git a/lib/dynamic.js b/lib/dynamic.js index 939e1114..43d49999 100644 --- a/lib/dynamic.js +++ b/lib/dynamic.js @@ -160,6 +160,11 @@ export function flushChunks () { } export class SameLoopPromise { + static resolve (value) { + const promise = new SameLoopPromise((done) => done(value)) + return promise + } + constructor (cb) { this.onResultCallbacks = [] this.onErrorCallbacks = [] diff --git a/lib/head.js b/lib/head.js index 5dadb1b6..71b374f9 100644 --- a/lib/head.js +++ b/lib/head.js @@ -33,7 +33,7 @@ function reduceComponents (components) { .filter(unique()) .reverse() .map((c) => { - const className = (c.className ? c.className + ' ' : '') + 'next-head' + const className = (c.props && c.props.className ? c.props.className + ' ' : '') + 'next-head' return React.cloneElement(c, { className }) }) } diff --git a/lib/link.js b/lib/link.js index c23a931f..ee16d715 100644 --- a/lib/link.js +++ b/lib/link.js @@ -153,6 +153,7 @@ export default class Link extends Component { function isLocal (href) { const url = parse(href, false, true) const origin = parse(getLocationOrigin(), false, true) + return !url.host || (url.protocol === origin.protocol && url.host === origin.host) } diff --git a/lib/router/router.js b/lib/router/router.js index 222499ab..f03107bf 100644 --- a/lib/router/router.js +++ b/lib/router/router.js @@ -129,7 +129,6 @@ export default class Router { } this.abortComponentLoad(as) - const { pathname, query } = parse(url, true) // If the url change is only related to a hash change // We should not proceed. We should only change the state. @@ -139,6 +138,8 @@ export default class Router { return } + const { pathname, query } = parse(url, true) + // If asked to change the current URL we should reload the current page // (not location.reload() but reload getInitalProps and other Next.js stuffs) // We also need to set the method = replaceState always @@ -209,10 +210,6 @@ export default class Router { this.components[route] = routeInfo } catch (err) { - if (err.cancelled) { - return { error: err } - } - if (err.buildIdMismatched) { // Now we need to reload the page or do the action asked by the user _notifyBuildIdMismatch(as) @@ -223,9 +220,21 @@ export default class Router { } if (err.statusCode === 404) { - // Indicate main error display logic to - // ignore rendering this error as a runtime error. - err.ignore = true + // If there's 404 error for the page, it could be due to two reasons. + // 1. Page is not exists + // 2. Page is exists in a different zone + // We are not sure whether this is actual 404 or exists in a different zone. + // So, doing a hard reload is the proper way to deal with this. + window.location.href = as + + // Changing the URL doesn't block executing the current code path. + // So, we need to mark it as a cancelled error and stop the routing logic. + err.cancelled = true + return { error: err } + } + + if (err.cancelled) { + return { error: err } } const Component = this.ErrorComponent @@ -301,29 +310,19 @@ export default class Router { cancelled = true } - try { - const Component = await this.fetchRoute(route) + const Component = await this.fetchRoute(route) - if (cancelled) { - const error = new Error(`Abort fetching component for route: "${route}"`) - error.cancelled = true - throw error - } - - if (cancel === this.componentLoadCancel) { - this.componentLoadCancel = null - } - - return Component - } catch (err) { - // There's an error in loading the route. - // Usually this happens when there's a failure in the webpack build - // So in that case, we need to load the page with full SSR - // That'll clean the invalid exising client side information. - // (Like cached routes) - window.location.href = as - throw err + if (cancelled) { + const error = new Error(`Abort fetching component for route: "${route}"`) + error.cancelled = true + throw error } + + if (cancel === this.componentLoadCancel) { + this.componentLoadCancel = null + } + + return Component } async getInitialProps (Component, ctx) { diff --git a/package.json b/package.json index 1f06ce8b..c51f0d6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "4.4.0-canary.3", + "version": "5.0.0-universal-alpha.14", "description": "Minimalistic framework for server-rendered React applications", "main": "./dist/server/next.js", "license": "MIT", @@ -18,6 +18,7 @@ "dynamic.js", "prefetch.js", "router.js", + "asset.js", "error.js" ], "bin": { @@ -29,8 +30,9 @@ "pretestonly": "taskr pretest", "testonly": "cross-env NODE_PATH=test/lib jest \\.test.js", "posttestonly": "taskr posttest", + "testall": "npm run testonly -- --coverage --forceExit --runInBand --verbose --bail", "pretest": "npm run lint", - "test": "npm run testonly -- --coverage --forceExit --runInBand --verbose --bail", + "test": "cross-env npm run testall || npm run testall", "coveralls": "nyc --instrument=false --source-map=false report --temp-directory=./coverage --reporter=text-lcov | coveralls", "lint": "standard 'bin/*' 'client/**/*.js' 'examples/**/*.js' 'lib/**/*.js' 'pages/**/*.js' 'server/**/*.js' 'test/**/*.js'", "prepublish": "npm run release", @@ -48,15 +50,13 @@ "bin/*": "standard" }, "dependencies": { + "@zeit/source-map-support": "0.6.0", "ansi-html": "0.0.7", "babel-core": "6.26.0", - "babel-generator": "6.26.0", "babel-loader": "7.1.2", - "babel-plugin-module-resolver": "2.7.1", "babel-plugin-react-require": "3.0.0", "babel-plugin-syntax-dynamic-import": "6.18.0", "babel-plugin-transform-class-properties": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", "babel-plugin-transform-object-rest-spread": "6.26.0", "babel-plugin-transform-react-jsx-source": "6.22.0", "babel-plugin-transform-react-remove-prop-types": "0.4.8", @@ -69,10 +69,11 @@ "cross-spawn": "5.1.0", "del": "3.0.0", "etag": "1.8.1", + "find-up": "2.1.0", "fresh": "0.5.2", "friendly-errors-webpack-plugin": "1.6.1", "glob": "7.1.2", - "glob-promise": "3.2.0", + "glob-promise": "3.3.0", "hoist-non-react-statics": "2.3.1", "htmlescape": "1.1.1", "http-status": "1.0.1", @@ -87,25 +88,25 @@ "pkg-up": "2.0.0", "prop-types": "15.6.0", "prop-types-exact": "1.1.1", - "react-hot-loader": "3.1.1", + "react-hot-loader": "4.0.0-beta.14", "recursive-copy": "2.0.6", + "resolve": "1.5.0", "send": "0.16.1", - "source-map-support": "0.4.18", "strip-ansi": "3.0.1", "styled-jsx": "2.2.1", "touch": "3.1.0", + "uglifyjs-webpack-plugin": "1.1.6", "unfetch": "3.0.0", "url": "0.11.0", "uuid": "3.1.0", "walk": "2.3.9", - "webpack": "3.6.0", + "webpack": "3.10.0", "webpack-dev-middleware": "1.12.0", - "webpack-hot-middleware": "2.19.1", + "webpack-hot-middleware": "2.21.0", "write-file-webpack-plugin": "4.2.0", "xss-filters": "1.2.7" }, "devDependencies": { - "uglifyjs-webpack-plugin": "^1.1.1", "@taskr/babel": "1.1.0", "@taskr/clear": "1.1.0", "@taskr/esnext": "1.1.0", @@ -129,8 +130,8 @@ "node-notifier": "5.1.2", "nyc": "11.2.1", "portfinder": "1.0.13", - "react": "16.0.0", - "react-dom": "16.0.0", + "react": "16.2.0", + "react-dom": "16.2.0", "standard": "9.0.2", "taskr": "1.1.0", "wd": "1.4.1" diff --git a/readme.md b/readme.md index d2fa37c2..54114c53 100644 --- a/readme.md +++ b/readme.md @@ -164,6 +164,14 @@ export default () =>

hi there

To use more sophisticated CSS-in-JS solutions, you typically have to implement style flushing for server-side rendering. We enable this by allowing you to define your own [custom ``](#user-content-custom-document) component that wraps each page. +#### Importing CSS / Sass / Less files + +To support importing `.css` `.scss` or `.less` files you can use these modules, which configure sensible defaults for server rendered applications. + +- ![@zeit/next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css) +- ![@zeit/next-sass](https://github.com/zeit/next-plugins/tree/master/packages/next-sass) +- ![@zeit/next-less](https://github.com/zeit/next-plugins/tree/master/packages/next-less) + ### Static file serving (e.g.: images) Create a folder called `static` in your project root directory. From your code you can then reference those files with `/static/` URLs: @@ -1006,7 +1014,7 @@ In order to extend our usage of `webpack`, you can define a function that extend // (But you could use ES2015 features supported by your Node.js version) module.exports = { - webpack: (config, { buildId, dev }) => { + webpack: (config, { buildId, dev, isServer, defaultLoaders }) => { // Perform customizations to webpack config // Important: return the modified config @@ -1021,7 +1029,15 @@ module.exports = { } ``` -*Warning: Adding loaders to support new file types (css, less, svg, etc.) is __not__ recommended because only the client code gets bundled via webpack and thus it won't work on the initial server rendering. Babel plugins are a good alternative because they're applied consistently between server/client rendering (e.g. [babel-plugin-inline-react-svg](https://github.com/kesne/babel-plugin-inline-react-svg)).* +Some commonly asked for features are available as modules: + +- ![@zeit/next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css) +- ![@zeit/next-sass](https://github.com/zeit/next-plugins/tree/master/packages/next-sass) +- ![@zeit/next-less](https://github.com/zeit/next-plugins/tree/master/packages/next-less) +- ![@zeit/next-preact](https://github.com/zeit/next-plugins/tree/master/packages/next-preact) +- ![@zeit/next-typescript](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript) + +*Warning: The `webpack` function is executed twice, once for the server and once for the client. This allows you to distinguish between client and server configuration using the `isServer` property* ### Customizing babel config @@ -1214,20 +1230,6 @@ If you want to create re-usable React components that you can embed in your Next Next.js bundles [styled-jsx](https://github.com/zeit/styled-jsx) supporting scoped css. However you can use any CSS-in-JS solution in your Next app by just including your favorite library [as mentioned before](#css-in-js) in the document. -
- How do I use CSS preprocessors like SASS / SCSS / LESS? - -Next.js bundles [styled-jsx](https://github.com/zeit/styled-jsx) supporting scoped css. However you can use any CSS preprocessor solution in your Next app by following one of these examples: - -- [with-external-scoped-css](./examples/with-external-scoped-css) -- [with-scoped-stylesheets-and-postcss](./examples/with-scoped-stylesheets-and-postcss) -- [with-global-stylesheet](./examples/with-global-stylesheet) -- [with-styled-jsx-scss](./examples/with-styled-jsx-scss) -- [with-styled-jsx-plugins](./examples/with-styled-jsx-plugins) - -
- -
What syntactic features are transpiled? How do I change them? diff --git a/server/build/babel/plugins/handle-import.js b/server/build/babel/plugins/handle-import.js index eb3d985a..86397e9e 100644 --- a/server/build/babel/plugins/handle-import.js +++ b/server/build/babel/plugins/handle-import.js @@ -16,32 +16,23 @@ const TYPE_IMPORT = 'Import' const buildImport = (args) => (template(` ( - typeof require.resolveWeak !== 'function' ? - new (require('next/dynamic').SameLoopPromise)((resolve, reject) => { - eval('require.ensure = function (deps, callback) { callback(require) }') - require.ensure([], (require) => { + new (require('next/dynamic').SameLoopPromise)((resolve, reject) => { + const weakId = require.resolveWeak(SOURCE) + try { + const weakModule = __webpack_require__(weakId) + return resolve(weakModule) + } catch (err) {} + + require.ensure([], (require) => { + try { let m = require(SOURCE) m.__webpackChunkName = '${args.name}' - resolve(m); - }, 'chunks/${args.name}'); - }) - : - new (require('next/dynamic').SameLoopPromise)((resolve, reject) => { - const weakId = require.resolveWeak(SOURCE) - try { - const weakModule = __webpack_require__(weakId) - return resolve(weakModule) - } catch (err) {} - - require.ensure([], (require) => { - try { - let m = require(SOURCE) - resolve(m) - } catch(error) { - reject(error) - } - }, 'chunks/${args.name}'); - }) + resolve(m) + } catch(error) { + reject(error) + } + }, 'chunks/${args.name}'); + }) ) `)) diff --git a/server/build/babel/plugins/remove-dotjsx-from-import.js b/server/build/babel/plugins/remove-dotjsx-from-import.js deleted file mode 100644 index b43b61ba..00000000 --- a/server/build/babel/plugins/remove-dotjsx-from-import.js +++ /dev/null @@ -1,15 +0,0 @@ -// This plugins removes the `.jsx` extension from import statements. Because we transpile .jsx files to .js in .next -// E.g. `import Hello from '../components/hello.jsx'` will become `import Hello from '../components/hello'` -module.exports = function ({types}) { - return { - name: 'remove-dotjsx-from-import', - visitor: { - ImportDeclaration (path) { - const value = path.node.source.value - if (value.slice(-4) === '.jsx') { - path.node.source = types.stringLiteral(value.slice(0, -4)) - } - } - } - } -} diff --git a/server/build/babel/preset.js b/server/build/babel/preset.js index a7d051b9..59c6e950 100644 --- a/server/build/babel/preset.js +++ b/server/build/babel/preset.js @@ -1,5 +1,3 @@ -const relativeResolve = require('../root-module-relative-path').default(require) - // Resolve styled-jsx plugins function styledJsxOptions (opts) { if (!opts) { @@ -45,29 +43,12 @@ module.exports = (context, opts = {}) => ({ require.resolve('babel-preset-react') ], plugins: [ - require.resolve('./plugins/remove-dotjsx-from-import'), require.resolve('babel-plugin-react-require'), require.resolve('./plugins/handle-import'), require.resolve('babel-plugin-transform-object-rest-spread'), require.resolve('babel-plugin-transform-class-properties'), [require.resolve('babel-plugin-transform-runtime'), opts['transform-runtime'] || {}], [require.resolve('styled-jsx/babel'), styledJsxOptions(opts['styled-jsx'])], - ...plugins, - [ - require.resolve('babel-plugin-module-resolver'), - { - alias: { - 'babel-runtime': relativeResolve('babel-runtime/package'), - 'next/link': relativeResolve('../../../lib/link'), - 'next/prefetch': relativeResolve('../../../lib/prefetch'), - 'next/css': relativeResolve('../../../lib/css'), - 'next/dynamic': relativeResolve('../../../lib/dynamic'), - 'next/head': relativeResolve('../../../lib/head'), - 'next/document': relativeResolve('../../../server/document'), - 'next/router': relativeResolve('../../../lib/router'), - 'next/error': relativeResolve('../../../lib/error') - } - } - ] + ...plugins ] }) diff --git a/server/build/index.js b/server/build/index.js index f1f3397d..4b7577bd 100644 --- a/server/build/index.js +++ b/server/build/index.js @@ -1,44 +1,42 @@ -import { tmpdir } from 'os' import { join } from 'path' import fs from 'mz/fs' import uuid from 'uuid' -import del from 'del' -import webpack from './webpack' -import replaceCurrentBuild from './replace' +import webpack from 'webpack' +import getConfig from '../config' +import getBaseWebpackConfig from './webpack' import md5File from 'md5-file/promise' export default async function build (dir, conf = null) { + const config = getConfig(dir, conf) const buildId = uuid.v4() - const tempDir = tmpdir() - const buildDir = join(tempDir, uuid.v4()) try { - await fs.access(tempDir, fs.constants.W_OK) + await fs.access(dir, fs.constants.W_OK) } catch (err) { console.error(`> Failed, build directory is not writeable. https://err.sh/zeit/next.js/build-dir-not-writeable`) throw err } - const compiler = await webpack(dir, { buildId, buildDir, conf }) - try { - const stats = await runCompiler(compiler) - await writeBuildStats(buildDir, stats) - await writeBuildId(buildDir, buildId) + const configs = await Promise.all([ + getBaseWebpackConfig(dir, { buildId, isServer: false, config }), + getBaseWebpackConfig(dir, { buildId, isServer: true, config }) + ]) + + await runCompiler(configs) + + await writeBuildStats(dir, config) + await writeBuildId(dir, buildId, config) } catch (err) { - console.error(`> Failed to build on ${buildDir}`) + console.error(`> Failed to build`) throw err } - - await replaceCurrentBuild(dir, buildDir) - - // no need to wait - del(buildDir, { force: true }) } function runCompiler (compiler) { - return new Promise((resolve, reject) => { - compiler.run((err, stats) => { + return new Promise(async (resolve, reject) => { + const webpackCompiler = await webpack(await compiler) + webpackCompiler.run((err, stats) => { if (err) return reject(err) const jsonStats = stats.toJson() @@ -55,21 +53,21 @@ function runCompiler (compiler) { }) } -async function writeBuildStats (dir, stats) { +async function writeBuildStats (dir, config) { // 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(dir, '.next', 'app.js')) + hash: await md5File(join(dir, config.distDir, 'app.js')) } } - const buildStatsPath = join(dir, '.next', 'build-stats.json') + const buildStatsPath = join(dir, config.distDir, 'build-stats.json') await fs.writeFile(buildStatsPath, JSON.stringify(assetHashMap), 'utf8') } -async function writeBuildId (dir, buildId) { - const buildIdPath = join(dir, '.next', 'BUILD_ID') +async function writeBuildId (dir, buildId, config) { + const buildIdPath = join(dir, config.distDir, 'BUILD_ID') await fs.writeFile(buildIdPath, buildId, 'utf8') } diff --git a/server/build/loaders/hot-self-accept-loader.js b/server/build/loaders/hot-self-accept-loader.js index 1c6968d2..3f0aa8cc 100644 --- a/server/build/loaders/hot-self-accept-loader.js +++ b/server/build/loaders/hot-self-accept-loader.js @@ -8,12 +8,6 @@ module.exports = function (content, sourceMap) { this.callback(null, `${content} (function (Component, route) { if (!module.hot) return - if (!__resourceQuery) return - - var qs = require('querystring') - var params = qs.parse(__resourceQuery.slice(1)) - if (params.entry == null) return - module.hot.accept() Component.__route = route diff --git a/server/build/plugins/nextjs-ssr-import.js b/server/build/plugins/nextjs-ssr-import.js new file mode 100644 index 00000000..d6de3ddb --- /dev/null +++ b/server/build/plugins/nextjs-ssr-import.js @@ -0,0 +1,29 @@ +import { join, sep } from 'path' + +// This plugin modifies the require-ensure code generated by Webpack +// to work with Next.js SSR +export default class NextJsSsrImportPlugin { + constructor ({ dir, dist }) { + this.dir = dir + this.dist = dist + } + + apply (compiler) { + compiler.plugin('compilation', (compilation) => { + compilation.mainTemplate.plugin('require-ensure', (code) => { + // Update to load chunks from our custom chunks directory + const chunksDirPath = join(this.dir, this.dist, 'dist') + let updatedCode = code.replace('require("./"', `require("${chunksDirPath}${sep}"`) + + // Replace a promise equivalent which runs in the same loop + // If we didn't do this webpack's module loading process block us from + // doing SSR for chunks + updatedCode = updatedCode.replace( + 'return Promise.resolve();', + `return require('next/dynamic').SameLoopPromise.resolve();` + ) + return updatedCode + }) + }) + } +} diff --git a/server/build/plugins/watch-pages-plugin.js b/server/build/plugins/watch-pages-plugin.js deleted file mode 100644 index c258c329..00000000 --- a/server/build/plugins/watch-pages-plugin.js +++ /dev/null @@ -1,27 +0,0 @@ -import { resolve, join } from 'path' - -export default class WatchPagesPlugin { - constructor (dir) { - this.dir = resolve(dir, 'pages') - } - - apply (compiler) { - compiler.plugin('compilation', (compilation) => { - compilation.plugin('optimize-assets', (assets, callback) => { - // transpile pages/_document.js and descendants, - // but don't need the bundle file - delete assets[join('bundles', 'pages', '_document.js')] - callback() - }) - }) - - compiler.plugin('emit', (compilation, callback) => { - // watch the pages directory - compilation.contextDependencies = [ - ...compilation.contextDependencies, - this.dir - ] - callback() - }) - } -} diff --git a/server/build/replace.js b/server/build/replace.js deleted file mode 100644 index 22ff9e4a..00000000 --- a/server/build/replace.js +++ /dev/null @@ -1,23 +0,0 @@ -import mv from 'mv' -import { join } from 'path' -import getConfig from '../config' - -export default async function replaceCurrentBuild (dir, buildDir) { - const dist = getConfig(dir).distDir - const _dir = join(dir, dist) - const _buildDir = join(buildDir, '.next') - const oldDir = join(buildDir, '.next.old') - - try { - await move(_dir, oldDir) - } catch (err) { - if (err.code !== 'ENOENT') throw err - } - await move(_buildDir, _dir) - return oldDir -} - -function move (from, to) { - return new Promise((resolve, reject) => - mv(from, to, err => err ? reject(err) : resolve())) -} diff --git a/server/build/webpack.js b/server/build/webpack.js index 02277eec..1fabfde4 100644 --- a/server/build/webpack.js +++ b/server/build/webpack.js @@ -1,242 +1,45 @@ -import { resolve, join, sep } from 'path' -import { createHash } from 'crypto' -import { realpathSync, existsSync } from 'fs' +import path, {sep} from 'path' import webpack from 'webpack' -import glob from 'glob-promise' +import resolve from 'resolve' +import UglifyJSPlugin from 'uglifyjs-webpack-plugin' +import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin' import WriteFilePlugin from 'write-file-webpack-plugin' import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin' -import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin' -import UglifyJSPlugin from 'uglifyjs-webpack-plugin' -import UnlinkFilePlugin from './plugins/unlink-file-plugin' -import PagesPlugin from './plugins/pages-plugin' -import DynamicChunksPlugin from './plugins/dynamic-chunks-plugin' +import {getPages} from './webpack/utils' import CombineAssetsPlugin from './plugins/combine-assets-plugin' -import getConfig from '../config' -import * as babelCore from 'babel-core' +import PagesPlugin from './plugins/pages-plugin' +import NextJsSsrImportPlugin from './plugins/nextjs-ssr-import' +import DynamicChunksPlugin from './plugins/dynamic-chunks-plugin' +import UnlinkFilePlugin from './plugins/unlink-file-plugin' import findBabelConfig from './babel/find-config' -import rootModuleRelativePath from './root-module-relative-path' -const documentPage = join('pages', '_document.js') +const nextDir = path.join(__dirname, '..', '..', '..') +const nextNodeModulesDir = path.join(nextDir, 'node_modules') +const nextPagesDir = path.join(nextDir, 'pages') const defaultPages = [ '_error.js', '_document.js' ] -const nextPagesDir = join(__dirname, '..', '..', 'pages') -const nextNodeModulesDir = join(__dirname, '..', '..', '..', 'node_modules') const interpolateNames = new Map(defaultPages.map((p) => { - return [join(nextPagesDir, p), `dist/pages/${p}`] + return [path.join(nextPagesDir, p), `dist/bundles/pages/${p}`] })) -const relativeResolve = rootModuleRelativePath(require) - -async function getPages ({dir, dev, pagesGlobPattern}) { - let pages - - if (dev) { - pages = await glob('pages/+(_document|_error).+(js|jsx)', { cwd: dir }) - } else { - pages = await glob(pagesGlobPattern, { cwd: dir }) - } - - return pages -} - -function getPageEntries (pages) { - const entries = {} - for (const p of pages) { - entries[join('bundles', p.replace('.jsx', '.js'))] = [`./${p}?entry`] - } - - // The default pages (_document.js and _error.js) are only added when they're not provided by the user - for (const p of defaultPages) { - const entryName = join('bundles', 'pages', p) - if (!entries[entryName]) { - entries[entryName] = [join(nextPagesDir, p) + '?entry'] - } - } - - return entries -} - -export default async function createCompiler (dir, { buildId, dev = false, quiet = false, buildDir, conf = null } = {}) { - // Resolve relative path to absolute path - dir = realpathSync(resolve(dir)) - - // Used to track the amount of pages for webpack commons chunk plugin - let totalPages - - // Loads next.config.js and custom configuration provided in custom server initialization - const config = getConfig(dir, conf) - - // Middlewares to handle on-demand entries and hot updates in development - const devEntries = dev ? [ - join(__dirname, '..', '..', 'client', 'webpack-hot-middleware-client'), - join(__dirname, '..', '..', 'client', 'on-demand-entries-client') - ] : [] - - const mainJS = require.resolve(`../../client/next${dev ? '-dev' : ''}`) // Uses client/next-dev in development for code splitting dev dependencies - - const entry = async () => { - // Get entries for pages in production mode. In development only _document and _error are added. Because pages are added by on-demand-entry-handler. - const pages = await getPages({dir, dev, pagesGlobPattern: config.pagesGlobPattern}) - const pageEntries = getPageEntries(pages) - - // Used for commons chunk calculations - totalPages = pages.length - if (pages.indexOf(documentPage) !== -1) { - totalPages = totalPages - 1 - } - - const entries = { - 'main.js': [ - ...devEntries, // Adds hot middleware and ondemand entries in development - ...config.clientBootstrap || [], // clientBootstrap can be used to load polyfills before code execution - mainJS // Main entrypoint in the client folder - ], - ...pageEntries - } - - return entries - } - - const plugins = [ - // Defines NODE_ENV as development/production. This is used by some npm modules to determine if they should optimize. - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production') - }), - new CaseSensitivePathPlugin(), // Since on macOS the filesystem is case-insensitive this will make sure your path are case-sensitive - new webpack.IgnorePlugin(/(precomputed)/, /node_modules.+(elliptic)/), - // Provide legacy options to webpack - new webpack.LoaderOptionsPlugin({ - options: { - context: dir, - customInterpolateName (url, name, opts) { - return interpolateNames.get(this.resourcePath) || url - } - } - }), - // Writes all generated files to disk, even in development. For SSR. - new WriteFilePlugin({ - exitOnErrors: false, - log: false, - // required not to cache removed files - useHashIndex: false - }), - // Moves common modules into commons.js - new webpack.optimize.CommonsChunkPlugin({ - name: 'commons', - filename: 'commons.js', - minChunks (module, count) { - // We need to move react-dom explicitly into common chunks. - // Otherwise, if some other page or module uses it, it might - // included in that bundle too. - if (dev && module.context && module.context.indexOf(`${sep}react${sep}`) >= 0) { - return true - } - - if (dev && module.context && module.context.indexOf(`${sep}react-dom${sep}`) >= 0) { - return true - } - - // In the dev we use on-demand-entries. - // So, it makes no sense to use commonChunks based on the minChunks count. - // Instead, we move all the code in node_modules into each of the pages. - if (dev) { - return false - } - - // If there are one or two pages, only move modules to common if they are - // used in all of the pages. Otherwise, move modules used in at-least - // 1/2 of the total pages into commons. - if (totalPages <= 2) { - return count >= totalPages - } - return count >= totalPages * 0.5 - } - }), - // This chunk splits out react and react-dom in production to make sure it does not go through uglify. This saved multiple seconds on production builds. - // See https://twitter.com/dan_abramov/status/944040306420408325 - new webpack.optimize.CommonsChunkPlugin({ - name: 'react', - filename: 'react.js', - minChunks (module, count) { - if (dev) { - return false - } - - if (module.resource && module.resource.includes(`${sep}react-dom${sep}`) && count >= 0) { - return true - } - - if (module.resource && module.resource.includes(`${sep}react${sep}`) && count >= 0) { - return true - } - - return false - } - }), - // This chunk contains all the webpack related code. So, all the changes - // related to that happens to this chunk. - // It won't touch commons.js and that gives us much better re-build perf. - new webpack.optimize.CommonsChunkPlugin({ - name: 'manifest', - filename: 'manifest.js' - }), - - // This adds Next.js route definitions to page bundles - new PagesPlugin(), - // Implements support for dynamic imports - new DynamicChunksPlugin() - ] - - if (dev) { - plugins.push( - new webpack.HotModuleReplacementPlugin(), - new webpack.NoEmitOnErrorsPlugin(), - new UnlinkFilePlugin() - ) - if (!quiet) { - plugins.push(new FriendlyErrorsWebpackPlugin()) - } - } else { - plugins.push(new webpack.IgnorePlugin(/react-hot-loader/)) - plugins.push( - // Minifies javascript bundles - new UglifyJSPlugin({ - exclude: /react\.js/, - parallel: true, - sourceMap: false, - uglifyOptions: { - compress: { - comparisons: false - } - } - }) - ) - plugins.push( - // Combines manifest.js commons.js and main.js into app.js in production - new CombineAssetsPlugin({ - input: ['manifest.js', 'react.js', 'commons.js', 'main.js'], - output: 'app.js' - }), - ) - // Implements scope hoisting which speeds up browser execution of javascript - plugins.push(new webpack.optimize.ModuleConcatenationPlugin()) - } - - const nodePathList = (process.env.NODE_PATH || '') - .split(process.platform === 'win32' ? ';' : ':') - .filter((p) => !!p) - +function babelConfig (dir, {isServer, dev}) { const mainBabelOptions = { cacheDirectory: true, - presets: [] + presets: [], + plugins: [ + dev && !isServer && require.resolve('react-hot-loader/babel') + ].filter(Boolean) } const externalBabelConfig = findBabelConfig(dir) if (externalBabelConfig) { - console.log(`> Using external babel configuration`) - console.log(`> Location: "${externalBabelConfig.loc}"`) + // Log it out once + if (!isServer) { + console.log(`> Using external babel configuration`) + console.log(`> Location: "${externalBabelConfig.loc}"`) + } // It's possible to turn off babelrc support via babelrc itself. // In that case, we should add our default preset. // That's why we need to do this. @@ -251,188 +54,252 @@ export default async function createCompiler (dir, { buildId, dev = false, quiet mainBabelOptions.presets.push(require.resolve('./babel/preset')) } - const devLoaders = dev ? [{ - test: /\.(js|jsx)(\?[^?]*)?$/, - loader: 'hot-self-accept-loader', - include: [ - join(dir, 'pages'), - nextPagesDir - ] - }, { - test: /\.(js|jsx)(\?[^?]*)?$/, - loader: 'react-hot-loader/webpack', - exclude: /node_modules/ - }] : [] + return mainBabelOptions +} - const loaders = [{ - test: /\.json$/, - loader: 'json-loader' - }, { - test: /\.(js|jsx|json)(\?[^?]*)?$/, - loader: 'emit-file-loader', - include: [dir, nextPagesDir], - exclude (str) { - return /node_modules/.test(str) && str.indexOf(nextPagesDir) !== 0 - }, - options: { - name: 'dist/[path][name].[ext]', - // We need to strip off .jsx on the server. Otherwise require without .jsx doesn't work. - interpolateName: (name) => name.replace('.jsx', '.js'), - validateFileName (file) { - const cases = [{from: '.js', to: '.jsx'}, {from: '.jsx', to: '.js'}] +function externalsConfig (dir, isServer) { + const externals = [] - for (const item of cases) { - const {from, to} = item - if (file.slice(-(from.length)) !== from) { - continue - } + if (!isServer) { + return externals + } - const filePath = file.slice(0, -(from.length)) + to - - if (existsSync(filePath)) { - throw new Error(`Both ${from} and ${to} file found. Please make sure you only have one of both.`) - } - } - }, - // By default, our babel config does not transpile ES2015 module syntax because - // webpack knows how to handle them. (That's how it can do tree-shaking) - // But Node.js doesn't know how to handle them. So, we have to transpile them here. - transform ({ content, sourceMap, interpolatedName }) { - // Only handle .js files - if (!(/\.(js|jsx)$/.test(interpolatedName))) { - return { content, sourceMap } - } - - const transpiled = babelCore.transform(content, { - babelrc: false, - sourceMaps: dev ? 'both' : false, - // Here we need to resolve all modules to the absolute paths. - // Earlier we did it with the babel-preset. - // But since we don't transpile ES2015 in the preset this is not resolving. - // That's why we need to do it here. - // See more: https://github.com/zeit/next.js/issues/951 - plugins: [ - require.resolve(join(__dirname, './babel/plugins/remove-dotjsx-from-import.js')), - [require.resolve('babel-plugin-transform-es2015-modules-commonjs')], - [ - require.resolve('babel-plugin-module-resolver'), - { - alias: { - 'babel-runtime': relativeResolve('babel-runtime/package'), - 'next/link': relativeResolve('../../lib/link'), - 'next/prefetch': relativeResolve('../../lib/prefetch'), - 'next/css': relativeResolve('../../lib/css'), - 'next/dynamic': relativeResolve('../../lib/dynamic'), - 'next/head': relativeResolve('../../lib/head'), - 'next/document': relativeResolve('../../server/document'), - 'next/router': relativeResolve('../../lib/router'), - 'next/error': relativeResolve('../../lib/error'), - 'styled-jsx/style': relativeResolve('styled-jsx/style') - } - } - ] - ], - inputSourceMap: sourceMap - }) - - // Strip ?entry to map back to filesystem and work with iTerm, etc. - let { map } = transpiled - let output = transpiled.code - - if (map) { - let nodeMap = Object.assign({}, map) - nodeMap.sources = nodeMap.sources.map((source) => source.replace(/\?entry/, '')) - delete nodeMap.sourcesContent - - // Output explicit inline source map that source-map-support can pickup via requireHook mode. - // Since these are not formal chunks, the devtool infrastructure in webpack does not output - // a source map for these files. - const sourceMapUrl = new Buffer(JSON.stringify(nodeMap), 'utf-8').toString('base64') - output = `${output}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${sourceMapUrl}` - } - - return { - content: output, - sourceMap: transpiled.map - } + // This will externalize all the 'next/xxx' modules to load from + // node_modules always. + // This is very useful in Next.js development where we use symlinked version + // of Next.js or using next/xxx inside test apps. + externals.push((context, request, callback) => { + resolve(request, { basedir: dir, preserveSymlinks: true }, (err, res) => { + if (err) { + return callback() } + + if (res.match(/node_modules/)) { + return callback(null, `commonjs ${request}`) + } + + callback() + }) + }) + + return externals +} + +export default async function getBaseWebpackConfig (dir, {dev = false, isServer = false, buildId, config}) { + const babelLoaderOptions = babelConfig(dir, {dev, isServer}) + + const defaultLoaders = { + babel: { + loader: 'babel-loader', + options: babelLoaderOptions } - }, { - loader: 'babel-loader', - include: nextPagesDir, - exclude (str) { - return /node_modules/.test(str) && str.indexOf(nextPagesDir) !== 0 - }, - options: { - babelrc: false, - cacheDirectory: true, - presets: [require.resolve('./babel/preset')] - } - }, { - test: /\.(js|jsx)(\?[^?]*)?$/, - loader: 'babel-loader', - include: [dir], - exclude (str) { - return /node_modules/.test(str) - }, - options: mainBabelOptions - }] + } + + let totalPages let webpackConfig = { + devtool: dev ? 'source-map' : false, + name: isServer ? 'server' : 'client', + cache: true, + target: isServer ? 'node' : 'web', + externals: externalsConfig(dir, isServer), context: dir, - entry, + entry: async () => { + const pages = await getPages(dir, {dev, isServer}) + totalPages = Object.keys(pages).length + const mainJS = require.resolve(`../../client/next${dev ? '-dev' : ''}`) + const clientConfig = !isServer ? { + 'main.js': [ + dev && !isServer && path.join(__dirname, '..', '..', 'client', 'webpack-hot-middleware-client'), + dev && !isServer && path.join(__dirname, '..', '..', 'client', 'on-demand-entries-client'), + mainJS + ].filter(Boolean) + } : {} + return { + ...clientConfig, + ...pages + } + }, output: { - path: buildDir ? join(buildDir, '.next') : join(dir, config.distDir), + path: path.join(dir, config.distDir, isServer ? 'dist' : ''), // server compilation goes to `.next/dist` filename: '[name]', libraryTarget: 'commonjs2', - publicPath: `/_next/webpack/`, - strictModuleExceptionHandling: true, - devtoolModuleFilenameTemplate ({ resourcePath }) { - const hash = createHash('sha1') - hash.update(Date.now() + '') - const id = hash.digest('hex').slice(0, 7) - - // append hash id for cache busting - return `webpack:///${resourcePath}?${id}` - }, + publicPath: `${config.assetPrefix}/_next/webpack/`, // This saves chunks with the name given via require.ensure() - chunkFilename: '[name]-[chunkhash].js' + chunkFilename: '[name]-[chunkhash].js', + strictModuleExceptionHandling: true, + devtoolModuleFilenameTemplate: '[absolute-resource-path]' }, + performance: { hints: false }, resolve: { - alias: { - // This bypasses React's check for production mode. Since we know it is in production this way. - // This allows us to exclude React from being uglified. Saving multiple seconds per build. - 'react-dom': dev ? 'react-dom/cjs/react-dom.development.js' : 'react-dom/cjs/react-dom.production.min.js' - }, extensions: ['.js', '.jsx', '.json'], modules: [ nextNodeModulesDir, - 'node_modules', - ...nodePathList - ] + 'node_modules' + ], + alias: { + next: nextDir, + // This bypasses React's check for production mode. Since we know it is in production this way. + // This allows us to exclude React from being uglified. Saving multiple seconds per build. + react: dev ? 'react/cjs/react.development.js' : 'react/cjs/react.production.min.js', + 'react-dom': dev ? 'react-dom/cjs/react-dom.development.js' : 'react-dom/cjs/react-dom.production.min.js' + } }, resolveLoader: { modules: [ nextNodeModulesDir, 'node_modules', - join(__dirname, 'loaders'), - ...nodePathList + path.join(__dirname, 'loaders') ] }, - plugins, module: { rules: [ - ...devLoaders, - ...loaders - ] + dev && !isServer && { + test: /\.(js|jsx)(\?[^?]*)?$/, + loader: 'hot-self-accept-loader', + include: [ + path.join(dir, 'pages'), + nextPagesDir + ] + }, + { + test: /\.+(js|jsx)$/, + include: [dir], + exclude: /node_modules/, + use: defaultLoaders.babel + } + ].filter(Boolean) }, - devtool: dev ? 'cheap-module-inline-source-map' : false, - performance: { hints: false } + plugins: [ + new webpack.IgnorePlugin(/(precomputed)/, /node_modules.+(elliptic)/), + dev && new webpack.NoEmitOnErrorsPlugin(), + dev && !isServer && new FriendlyErrorsWebpackPlugin(), + dev && new webpack.NamedModulesPlugin(), + dev && !isServer && new webpack.HotModuleReplacementPlugin(), // Hot module replacement + dev && new UnlinkFilePlugin(), + dev && new CaseSensitivePathPlugin(), // Since on macOS the filesystem is case-insensitive this will make sure your path are case-sensitive + dev && new webpack.LoaderOptionsPlugin({ + options: { + context: dir, + customInterpolateName (url, name, opts) { + return interpolateNames.get(this.resourcePath) || url + } + } + }), + dev && new WriteFilePlugin({ + exitOnErrors: false, + log: false, + // required not to cache removed files + useHashIndex: false + }), + !dev && new webpack.IgnorePlugin(/react-hot-loader/), + !isServer && !dev && new UglifyJSPlugin({ + exclude: /react\.js/, + parallel: true, + sourceMap: false, + uglifyOptions: { + compress: { + arrows: false, + booleans: false, + collapse_vars: false, + comparisons: false, + computed_props: false, + hoist_funs: false, + hoist_props: false, + hoist_vars: false, + if_return: false, + inline: false, + join_vars: false, + keep_infinity: true, + loops: false, + negate_iife: false, + properties: false, + reduce_funcs: false, + reduce_vars: false, + sequences: false, + side_effects: false, + switches: false, + top_retain: false, + toplevel: false, + typeofs: false, + unused: false, + conditionals: false, + dead_code: true, + evaluate: false + } + } + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(dev ? 'development' : 'production') + }), + !isServer && new CombineAssetsPlugin({ + input: ['manifest.js', 'react.js', 'commons.js', 'main.js'], + output: 'app.js' + }), + !dev && new webpack.optimize.ModuleConcatenationPlugin(), + !isServer && new PagesPlugin(), + !isServer && new DynamicChunksPlugin(), + isServer && new NextJsSsrImportPlugin({ dir, dist: config.distDir }), + !isServer && new webpack.optimize.CommonsChunkPlugin({ + name: `commons`, + filename: `commons.js`, + minChunks (module, count) { + // We need to move react-dom explicitly into common chunks. + // Otherwise, if some other page or module uses it, it might + // included in that bundle too. + if (dev && module.context && module.context.indexOf(`${sep}react${sep}`) >= 0) { + return true + } + + if (dev && module.context && module.context.indexOf(`${sep}react-dom${sep}`) >= 0) { + return true + } + + // In the dev we use on-demand-entries. + // So, it makes no sense to use commonChunks based on the minChunks count. + // Instead, we move all the code in node_modules into each of the pages. + if (dev) { + return false + } + + // If there are one or two pages, only move modules to common if they are + // used in all of the pages. Otherwise, move modules used in at-least + // 1/2 of the total pages into commons. + if (totalPages <= 2) { + return count >= totalPages + } + return count >= totalPages * 0.5 + } + }), + !isServer && new webpack.optimize.CommonsChunkPlugin({ + name: 'react', + filename: 'react.js', + minChunks (module, count) { + if (dev) { + return false + } + + if (module.resource && module.resource.includes(`${sep}react-dom${sep}`) && count >= 0) { + return true + } + + if (module.resource && module.resource.includes(`${sep}react${sep}`) && count >= 0) { + return true + } + + return false + } + }), + !isServer && new webpack.optimize.CommonsChunkPlugin({ + name: 'manifest', + filename: 'manifest.js' + }) + ].filter(Boolean) } - if (config.webpack) { - console.log(`> Using "webpack" config function defined in ${config.configOrigin}.`) - webpackConfig = await config.webpack(webpackConfig, { buildId, dev }) + if (typeof config.webpack === 'function') { + webpackConfig = config.webpack(webpackConfig, {dir, dev, isServer, buildId, config, defaultLoaders}) } - return webpack(webpackConfig) + + return webpackConfig } diff --git a/server/build/webpack/utils.js b/server/build/webpack/utils.js new file mode 100644 index 00000000..60e64909 --- /dev/null +++ b/server/build/webpack/utils.js @@ -0,0 +1,68 @@ +import path from 'path' +import glob from 'glob-promise' + +const nextPagesDir = path.join(__dirname, '..', '..', '..', 'pages') + +export async function getPages (dir, {dev, isServer}) { + const pageFiles = await getPagePaths(dir, {dev, isServer}) + + return getPageEntries(pageFiles, {isServer}) +} + +async function getPagePaths (dir, {dev, isServer}) { + let pages + + if (dev) { + pages = await glob(isServer ? 'pages/+(_document|_error).+(js|jsx|ts|tsx)' : 'pages/_error.+(js|jsx|ts|tsx)', { cwd: dir }) + } else { + pages = await glob(isServer ? 'pages/**/*.+(js|jsx|ts|tsx)' : 'pages/**/!(_document)*.+(js|jsx|ts|tsx)', { cwd: dir }) + } + + return pages +} + +// Convert page path into single entry +export function createEntry (filePath, name) { + const parsedPath = path.parse(filePath) + let entryName = name || filePath + + // This makes sure we compile `pages/blog/index.js` to `pages/blog.js`. + // Excludes `pages/index.js` from this rule since we do want `/` to route to `pages/index.js` + if (parsedPath.dir !== 'pages' && parsedPath.name === 'index') { + entryName = `${parsedPath.dir}.js` + } + + // Makes sure supported extensions are stripped off. The outputted file should always be `.js` + entryName = entryName.replace(/\.+(jsx|tsx|ts)/, '.js') + + return { + name: path.join('bundles', entryName), + files: [parsedPath.root ? filePath : `./${filePath}`] // The entry always has to be an array. + } +} + +// Convert page paths into entries +export function getPageEntries (pagePaths, {isServer}) { + const entries = {} + + for (const filePath of pagePaths) { + const entry = createEntry(filePath) + entries[entry.name] = entry.files + } + + const errorPagePath = path.join(nextPagesDir, '_error.js') + const errorPageEntry = createEntry(errorPagePath, 'pages/_error.js') // default error.js + if (!entries[errorPageEntry.name]) { + entries[errorPageEntry.name] = errorPageEntry.files + } + + if (isServer) { + const documentPagePath = path.join(nextPagesDir, '_document.js') + const documentPageEntry = createEntry(documentPagePath, 'pages/_document.js') + if (!entries[documentPageEntry.name]) { + entries[documentPageEntry.name] = documentPageEntry.files + } + } + + return entries +} diff --git a/server/config.js b/server/config.js index 395b92c5..5aabc60b 100644 --- a/server/config.js +++ b/server/config.js @@ -5,12 +5,10 @@ const cache = new Map() const defaultConfig = { webpack: null, webpackDevMiddleware: null, - poweredByHeader: true, distDir: '.next', assetPrefix: '', configOrigin: 'default', - useFileSystemPublicRoutes: true, - pagesGlobPattern: 'pages/**/*.+(js|jsx)' + useFileSystemPublicRoutes: true } export default function getConfig (dir, customConfig) { @@ -34,6 +32,9 @@ function loadConfig (dir, customConfig) { if (path && path.length) { const userConfigModule = require(path) userConfig = userConfigModule.default || userConfigModule + if (userConfig.poweredByHeader === true || userConfig.poweredByHeader === false) { + console.warn('> the `poweredByHeader` option has been removed https://err.sh/zeit/next.js/powered-by-header-option-removed') + } userConfig.configOrigin = 'next.config.js' } diff --git a/server/document.js b/server/document.js index 05de0316..49eea8a5 100644 --- a/server/document.js +++ b/server/document.js @@ -4,7 +4,7 @@ import htmlescape from 'htmlescape' import flush from 'styled-jsx/server' const Fragment = React.Fragment || function Fragment ({ children }) { - return children + return
{children}
} export default class Document extends Component { @@ -106,7 +106,6 @@ export class Main extends Component { render () { const { html, errorHtml } = this.context._documentProps - return (
diff --git a/server/hot-reloader.js b/server/hot-reloader.js index 94ffa550..fb4b92de 100644 --- a/server/hot-reloader.js +++ b/server/hot-reloader.js @@ -2,12 +2,14 @@ import { join, relative, sep } from 'path' import WebpackDevMiddleware from 'webpack-dev-middleware' import WebpackHotMiddleware from 'webpack-hot-middleware' import onDemandEntryHandler from './on-demand-entry-handler' -import webpack from './build/webpack' +import webpack from 'webpack' +import getBaseWebpackConfig from './build/webpack' import clean from './build/clean' import getConfig from './config' import UUID from 'uuid' import { - IS_BUNDLED_PAGE + IS_BUNDLED_PAGE, + addCorsSupport } from './utils' export default class HotReloader { @@ -34,6 +36,15 @@ export default class HotReloader { } async run (req, res) { + // Usually CORS support is not needed for the hot-reloader (this is dev only feature) + // With when the app runs for multi-zones support behind a proxy, + // the current page is trying to access this URL via assetPrefix. + // That's when the CORS support is needed. + const { preflight } = addCorsSupport(req, res) + if (preflight) { + return + } + for (const fn of this.middlewares) { await new Promise((resolve, reject) => { fn(req, res, (err) => { @@ -45,15 +56,19 @@ export default class HotReloader { } async start () { - const [compiler] = await Promise.all([ - webpack(this.dir, { buildId: this.buildId, dev: true, quiet: this.quiet }), - clean(this.dir) + await clean(this.dir) + + const configs = await Promise.all([ + getBaseWebpackConfig(this.dir, { dev: true, isServer: false, config: this.config }), + getBaseWebpackConfig(this.dir, { dev: true, isServer: true, config: this.config }) ]) + const compiler = webpack(configs) + const buildTools = await this.prepareBuildTools(compiler) this.assignBuildTools(buildTools) - this.stats = await this.waitUntilValid() + this.stats = (await this.waitUntilValid()).stats[0] } async stop (webpackDevMiddleware) { @@ -71,11 +86,15 @@ export default class HotReloader { async reload () { this.stats = null - const [compiler] = await Promise.all([ - webpack(this.dir, { buildId: this.buildId, dev: true, quiet: this.quiet }), - clean(this.dir) + await clean(this.dir) + + const configs = await Promise.all([ + getBaseWebpackConfig(this.dir, { dev: true, isServer: false, config: this.config }), + getBaseWebpackConfig(this.dir, { dev: true, isServer: true, config: this.config }) ]) + const compiler = webpack(configs) + const buildTools = await this.prepareBuildTools(compiler) this.stats = await this.waitUntilValid(buildTools.webpackDevMiddleware) @@ -97,25 +116,28 @@ export default class HotReloader { } async prepareBuildTools (compiler) { - compiler.plugin('after-emit', (compilation, callback) => { - const { assets } = compilation + // This flushes require.cache after emitting the files. Providing 'hot reloading' of server files. + compiler.compilers.forEach((singleCompiler) => { + singleCompiler.plugin('after-emit', (compilation, callback) => { + const { assets } = compilation - if (this.prevAssets) { - for (const f of Object.keys(assets)) { - deleteCache(assets[f].existsAt) - } - for (const f of Object.keys(this.prevAssets)) { - if (!assets[f]) { - deleteCache(this.prevAssets[f].existsAt) + if (this.prevAssets) { + for (const f of Object.keys(assets)) { + deleteCache(assets[f].existsAt) + } + for (const f of Object.keys(this.prevAssets)) { + if (!assets[f]) { + deleteCache(this.prevAssets[f].existsAt) + } } } - } - this.prevAssets = assets + this.prevAssets = assets - callback() + callback() + }) }) - compiler.plugin('done', (stats) => { + compiler.compilers[0].plugin('done', (stats) => { const { compilation } = stats const chunkNames = new Set( compilation.chunks @@ -193,12 +215,13 @@ export default class HotReloader { const webpackDevMiddleware = WebpackDevMiddleware(compiler, webpackDevMiddlewareConfig) - const webpackHotMiddleware = WebpackHotMiddleware(compiler, { + const webpackHotMiddleware = WebpackHotMiddleware(compiler.compilers[0], { path: '/_next/webpack-hmr', log: false, heartbeat: 2500 }) - const onDemandEntries = onDemandEntryHandler(webpackDevMiddleware, compiler, { + + const onDemandEntries = onDemandEntryHandler(webpackDevMiddleware, compiler.compilers, { dir: this.dir, dev: true, reload: this.reload.bind(this), @@ -249,8 +272,8 @@ export default class HotReloader { this.webpackHotMiddleware.publish({ action, data: args }) } - ensurePage (page) { - return this.onDemandEntries.ensurePage(page) + async ensurePage (page) { + await this.onDemandEntries.ensurePage(page) } } diff --git a/server/index.js b/server/index.js index 31d1c815..6b349382 100644 --- a/server/index.js +++ b/server/index.js @@ -1,3 +1,4 @@ +require('@zeit/source-map-support').install() import { resolve, join, sep } from 'path' import { parse as parseUrl } from 'url' import { parse as parseQs } from 'querystring' @@ -11,28 +12,11 @@ import { renderScriptError } from './render' import Router from './router' -import { getAvailableChunks } from './utils' +import { getAvailableChunks, isInternalUrl } from './utils' import getConfig from './config' // We need to go up one more level since we are in the `dist` directory import pkg from '../../package' -import reactPkg from 'react/package' - -// TODO: Remove this in Next.js 5 -if (!(/^16\./.test(reactPkg.version))) { - const message = ` -Error: Next.js 4 requires React 16. -Install React 16 with: - npm remove react react-dom - npm install --save react@16 react-dom@16 -` - console.error(message) - process.exit(1) -} - -const internalPrefixes = [ - /^\/_next\//, - /^\/static\// -] +import * as asset from '../lib/asset' const blockedPages = { '/_document': true, @@ -41,14 +25,6 @@ const blockedPages = { export default class Server { constructor ({ dir = '.', dev = false, staticMarkup = false, quiet = false, conf = null } = {}) { - // When in dev mode, remap the inline source maps that we generate within the webpack portion - // of the build. - if (dev) { - require('source-map-support').install({ - hookRequire: true - }) - } - this.dir = resolve(dir) this.dev = dev this.quiet = quiet @@ -74,6 +50,9 @@ export default class Server { availableChunks: dev ? {} : getAvailableChunks(this.dir, this.dist) } + // With this, static assets will work across zones + asset.setAssetPrefix(this.config.assetPrefix) + this.defineRoutes() } @@ -182,6 +161,23 @@ export default class Server { await this.serveStatic(req, res, p) }, + '/_next/:buildId/page/:path*.js.map': async (req, res, params) => { + const paths = params.path || [''] + const page = `/${paths.join('/')}` + + if (this.dev) { + try { + await this.hotReloader.ensurePage(page) + } catch (err) { + await this.render404(req, res) + } + } + + const dist = getConfig(this.dir).distDir + const path = join(this.dir, dist, 'bundles', 'pages', `${page}.js.map`) + await serveStatic(req, res, path) + }, + '/_next/:buildId/page/_error*': async (req, res, params) => { if (!this.handleBuildId(params.buildId, res)) { const error = new Error('INVALID_BUILD_ID') @@ -196,9 +192,6 @@ export default class Server { '/_next/:buildId/page/:path*.js': async (req, res, params) => { const paths = params.path || [''] - // URL is asks for ${page}.js (to support loading assets from static dirs) - // But there's no .js in the actual page. - // So, we need to remove .js to get the page name. const page = `/${paths.join('/')}` if (!this.handleBuildId(params.buildId, res)) { @@ -222,11 +215,13 @@ export default class Server { } } - let p = join(this.dir, this.dist, 'bundles', 'pages', paths.join('/')) - if (!fs.existsSync(`${p}.js`)) { - p = join(p, 'index') // It's possible to have index.js in a subfolder - } - await this.serveStatic(req, res, `${p}.js`) + const p = join(this.dir, this.dist, 'bundles', 'pages', `${page}.js`) + await this.serveStatic(req, res, p) + }, + + '/_next/static/:path*': async (req, res, params) => { + const p = join(this.dist, 'static', ...(params.path || [])) + await this.serveStatic(req, res, p) }, // It's very important keep this route's param optional. @@ -293,7 +288,7 @@ export default class Server { } async render (req, res, pathname, query, parsedUrl) { - if (this.isInternalUrl(req)) { + if (isInternalUrl(req.url)) { return this.handleRequest(req, res, parsedUrl) } @@ -301,10 +296,8 @@ export default class Server { return await this.render404(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) + res.setHeader('X-Powered-By', `Next.js ${pkg.version}`) return sendHTML(req, res, html, req.method, this.renderOpts) } @@ -318,7 +311,8 @@ export default class Server { } try { - return await renderToHTML(req, res, pathname, query, this.renderOpts) + const out = await renderToHTML(req, res, pathname, query, this.renderOpts) + return out } catch (err) { if (err.code === 'ENOENT') { res.statusCode = 404 @@ -393,16 +387,6 @@ export default class Server { return true } - 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') diff --git a/server/on-demand-entry-handler.js b/server/on-demand-entry-handler.js index fdd55328..f723c951 100644 --- a/server/on-demand-entry-handler.js +++ b/server/on-demand-entry-handler.js @@ -1,20 +1,21 @@ import DynamicEntryPlugin from 'webpack/lib/DynamicEntryPlugin' import { EventEmitter } from 'events' -import { join } from 'path' +import { join, relative } from 'path' import { parse } from 'url' -import resolvePath from './resolve' import touch from 'touch' +import resolvePath from './resolve' +import {createEntry} from './build/webpack/utils' import { MATCH_ROUTE_NAME, IS_BUNDLED_PAGE } from './utils' const ADDED = Symbol('added') const BUILDING = Symbol('building') const BUILT = Symbol('built') -export default function onDemandEntryHandler (devMiddleware, compiler, { +export default function onDemandEntryHandler (devMiddleware, compilers, { dir, dev, reload, - maxInactiveAge = 1000 * 25, + maxInactiveAge = 1000 * 60, pagesBufferLength = 2 }) { let entries = {} @@ -25,81 +26,90 @@ export default function onDemandEntryHandler (devMiddleware, compiler, { let reloading = false let stopped = false let reloadCallbacks = new EventEmitter() + // Keep the names of compilers which are building pages at a given moment. + const currentBuilders = new Set() - compiler.plugin('make', function (compilation, done) { - invalidator.startBuilding() + compilers.forEach(compiler => { + compiler.plugin('make', function (compilation, done) { + invalidator.startBuilding() + currentBuilders.add(compiler.name) - const allEntries = Object.keys(entries).map((page) => { - const { name, entry } = entries[page] - entries[page].status = BUILDING - return addEntry(compilation, this.context, name, entry) + const allEntries = Object.keys(entries).map((page) => { + const { name, entry } = entries[page] + entries[page].status = BUILDING + return addEntry(compilation, this.context, name, entry) + }) + + Promise.all(allEntries) + .then(() => done()) + .catch(done) }) - Promise.all(allEntries) - .then(() => done()) - .catch(done) - }) + compiler.plugin('done', function (stats) { + // Wait until all the compilers mark the build as done. + currentBuilders.delete(compiler.name) + if (currentBuilders.size !== 0) return - compiler.plugin('done', function (stats) { - const { compilation } = stats - const hardFailedPages = compilation.errors - .filter(e => { - // Make sure to only pick errors which marked with missing modules - const hasNoModuleFoundError = /ENOENT/.test(e.message) || /Module not found/.test(e.message) - if (!hasNoModuleFoundError) return false + const { compilation } = stats + const hardFailedPages = compilation.errors + .filter(e => { + // Make sure to only pick errors which marked with missing modules + const hasNoModuleFoundError = /ENOENT/.test(e.message) || /Module not found/.test(e.message) + if (!hasNoModuleFoundError) return false - // The page itself is missing. So this is a failed page. - if (IS_BUNDLED_PAGE.test(e.module.name)) return true + // The page itself is missing. So this is a failed page. + if (IS_BUNDLED_PAGE.test(e.module.name)) return true - // No dependencies means this is a top level page. - // So this is a failed page. - return e.module.dependencies.length === 0 - }) - .map(e => e.module.chunks) - .reduce((a, b) => [...a, ...b], []) - .map(c => { - const pageName = MATCH_ROUTE_NAME.exec(c.name)[1] - return normalizePage(`/${pageName}`) + // No dependencies means this is a top level page. + // So this is a failed page. + return e.module.dependencies.length === 0 + }) + .map(e => e.module.chunks) + .reduce((a, b) => [...a, ...b], []) + .map(c => { + const pageName = MATCH_ROUTE_NAME.exec(c.name)[1] + return normalizePage(`/${pageName}`) + }) + + // Call all the doneCallbacks + Object.keys(entries).forEach((page) => { + const entryInfo = entries[page] + if (entryInfo.status !== BUILDING) return + + // With this, we are triggering a filesystem based watch trigger + // It'll memorize some timestamp related info related to common files used + // in the page + // That'll reduce the page building time significantly. + if (!touchedAPage) { + setTimeout(() => { + touch.sync(entryInfo.pathname) + }, 1000) + touchedAPage = true + } + + entryInfo.status = BUILT + entries[page].lastActiveTime = Date.now() + doneCallbacks.emit(page) }) - // Call all the doneCallbacks - Object.keys(entries).forEach((page) => { - const entryInfo = entries[page] - if (entryInfo.status !== BUILDING) return + invalidator.doneBuilding(compiler.name) - // With this, we are triggering a filesystem based watch trigger - // It'll memorize some timestamp related info related to common files used - // in the page - // That'll reduce the page building time significantly. - if (!touchedAPage) { - setTimeout(() => { - touch.sync(entryInfo.pathname) - }, 1000) - touchedAPage = true + if (hardFailedPages.length > 0 && !reloading) { + console.log(`> Reloading webpack due to inconsistant state of pages(s): ${hardFailedPages.join(', ')}`) + reloading = true + reload() + .then(() => { + console.log('> Webpack reloaded.') + reloadCallbacks.emit('done') + stop() + }) + .catch(err => { + console.error(`> Webpack reloading failed: ${err.message}`) + console.error(err.stack) + process.exit(1) + }) } - - entryInfo.status = BUILT - entries[page].lastActiveTime = Date.now() - doneCallbacks.emit(page) }) - - invalidator.doneBuilding() - - if (hardFailedPages.length > 0 && !reloading) { - console.log(`> Reloading webpack due to inconsistant state of pages(s): ${hardFailedPages.join(', ')}`) - reloading = true - reload() - .then(() => { - console.log('> Webpack reloaded.') - reloadCallbacks.emit('done') - stop() - }) - .catch(err => { - console.error(`> Webpack reloading failed: ${err.message}`) - console.error(err.stack) - process.exit(1) - }) - } }) const disposeHandler = setInterval(function () { @@ -130,9 +140,7 @@ export default function onDemandEntryHandler (devMiddleware, compiler, { const pagePath = join(dir, 'pages', page) const pathname = await resolvePath(pagePath) - const name = join('bundles', pathname.substring(dir.length)) - - const entry = [`${pathname}?entry`] + const {name, files} = createEntry(relative(dir, pathname)) await new Promise((resolve, reject) => { const entryInfo = entries[page] @@ -144,19 +152,19 @@ export default function onDemandEntryHandler (devMiddleware, compiler, { } if (entryInfo.status === BUILDING) { - doneCallbacks.on(page, processCallback) + doneCallbacks.once(page, handleCallback) return } } console.log(`> Building page: ${page}`) - entries[page] = { name, entry, pathname, status: ADDED } - doneCallbacks.on(page, processCallback) + entries[page] = { name, entry: files, pathname, status: ADDED } + doneCallbacks.once(page, handleCallback) invalidator.invalidate() - function processCallback (err) { + function handleCallback (err) { if (err) return reject(err) resolve() } @@ -216,6 +224,7 @@ export default function onDemandEntryHandler (devMiddleware, compiler, { } } +// Based on https://github.com/webpack/webpack/blob/master/lib/DynamicEntryPlugin.js#L29-L37 function addEntry (compilation, context, name, entry) { return new Promise((resolve, reject) => { const dep = DynamicEntryPlugin.createDependency(entry, name) @@ -272,6 +281,7 @@ function sendJson (res, payload) { class Invalidator { constructor (devMiddleware) { this.devMiddleware = devMiddleware + // contains an array of types of compilers currently building this.building = false this.rebuildAgain = false } @@ -296,6 +306,7 @@ class Invalidator { doneBuilding () { this.building = false + if (this.rebuildAgain) { this.rebuildAgain = false this.invalidate() diff --git a/server/render.js b/server/render.js index d3ab29ce..e56bdbb7 100644 --- a/server/render.js +++ b/server/render.js @@ -6,7 +6,6 @@ import generateETag from 'etag' import fresh from 'fresh' import requireModule from './require' import getConfig from './config' -import resolvePath from './resolve' import { Router } from '../lib/router' import { loadGetInitialProps } from '../lib/utils' import { getAvailableChunks } from './utils' @@ -53,9 +52,12 @@ async function doRender (req, res, pathname, query, { const dist = getConfig(dir).distDir + const pagePath = join(dir, dist, 'dist', 'bundles', 'pages', page) + const documentPath = join(dir, dist, 'dist', 'bundles', 'pages', '_document') + let [Component, Document] = await Promise.all([ - requireModule(join(dir, dist, 'dist', 'pages', page)), - requireModule(join(dir, dist, 'dist', 'pages', '_document')) + requireModule(pagePath), + requireModule(documentPath) ]) Component = Component.default || Component Document = Document.default || Document @@ -120,22 +122,6 @@ async function doRender (req, res, pathname, query, { return '' + renderToStaticMarkup(doc) } -export async function renderScript (req, res, page, opts) { - try { - const dist = getConfig(opts.dir).distDir - const path = join(opts.dir, dist, 'bundles', 'pages', page) - const realPath = await resolvePath(path) - await serveStatic(req, res, realPath) - } catch (err) { - if (err.code === 'ENOENT') { - renderScriptError(req, res, page, err, {}, opts) - return - } - - throw err - } -} - export async function renderScriptError (req, res, page, error, customFields, { dev }) { // Asks CDNs and others to not to cache the errored page res.setHeader('Cache-Control', 'no-store, must-revalidate') diff --git a/server/resolve.js b/server/resolve.js index 543dded7..d33fee65 100644 --- a/server/resolve.js +++ b/server/resolve.js @@ -28,12 +28,16 @@ function getPaths (id) { if (i.slice(-3) === '.js') return [i] if (i.slice(-4) === '.jsx') return [i] + if (i.slice(-4) === '.tsx') return [i] + if (i.slice(-3) === '.ts') return [i] if (i.slice(-5) === '.json') return [i] if (i[i.length - 1] === sep) { return [ i + 'index.js', i + 'index.jsx', + i + 'index.ts', + i + 'index.tsx', i + 'index.json' ] } @@ -43,6 +47,10 @@ function getPaths (id) { join(i, 'index.js'), i + '.jsx', join(i, 'index.jsx'), + i + '.tsx', + join(i, 'index.tsx'), + i + '.ts', + join(i, 'index.ts'), i + '.json', join(i, 'index.json') ] diff --git a/server/utils.js b/server/utils.js index 5821a861..3e546e8b 100644 --- a/server/utils.js +++ b/server/utils.js @@ -1,8 +1,8 @@ import { join } from 'path' import { readdirSync, existsSync } from 'fs' -export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.(js|jsx)$/ -export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.(js|jsx)$/ +export const IS_BUNDLED_PAGE = /^bundles[/\\]pages.*\.js$/ +export const MATCH_ROUTE_NAME = /^bundles[/\\]pages[/\\](.*)\.js$/ export function getAvailableChunks (dir, dist) { const chunksDir = join(dir, dist, 'chunks') @@ -20,3 +20,37 @@ export function getAvailableChunks (dir, dist) { return chunksMap } + +const internalPrefixes = [ + /^\/_next\//, + /^\/static\// +] + +export function isInternalUrl (url) { + for (const prefix of internalPrefixes) { + if (prefix.test(url)) { + return true + } + } + + return false +} + +export function addCorsSupport (req, res) { + if (!req.headers.origin) { + return { preflight: false } + } + + res.setHeader('Access-Control-Allow-Origin', req.headers.origin) + res.setHeader('Access-Control-Request-Method', req.headers.origin) + res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET') + res.setHeader('Access-Control-Allow-Headers', req.headers.origin) + + if (req.method === 'OPTIONS') { + res.writeHead(200) + res.end() + return { preflight: true } + } + + return { preflight: false } +} diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 00000000..cf4bab9d --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +!node_modules diff --git a/test/integration/basic/test/dynamic.js b/test/integration/basic/test/dynamic.js index 1744e4a1..7c83c774 100644 --- a/test/integration/basic/test/dynamic.js +++ b/test/integration/basic/test/dynamic.js @@ -11,17 +11,17 @@ export default (context, render) => { return cheerio.load(html) } - it('should render dynmaic import components', async () => { + it('should render dynamic import components', async () => { const $ = await get$('/dynamic/ssr') expect($('p').text()).toBe('Hello World 1') }) - it('should stop render dynmaic import components', async () => { + it('should stop render dynamic import components', async () => { const $ = await get$('/dynamic/no-ssr') expect($('p').text()).toBe('loading...') }) - it('should stop render dynmaic import components with custom loading', async () => { + it('should stop render dynamic import components with custom loading', async () => { const $ = await get$('/dynamic/no-ssr-custom-loading') expect($('p').text()).toBe('LOADING') }) diff --git a/test/integration/production/test/index.test.js b/test/integration/production/test/index.test.js index 217818f9..1916c81a 100644 --- a/test/integration/production/test/index.test.js +++ b/test/integration/production/test/index.test.js @@ -145,26 +145,6 @@ describe('Production Usage', () => { await app.render(req, res, req.url) expect(headers['X-Powered-By']).toEqual(`Next.js ${pkg.version}`) }) - - it('should not set it when poweredByHeader==false', async () => { - const req = { url: '/stateless', headers: {} } - const originalConfigValue = app.config.poweredByHeader - app.config.poweredByHeader = false - const res = { - getHeader () { - return false - }, - setHeader (key, value) { - if (key === 'X-Powered-By') { - throw new Error('Should not set the X-Powered-By header') - } - }, - end () {} - } - - await app.render(req, res, req.url) - app.config.poweredByHeader = originalConfigValue - }) }) dynamicImportTests(context, (p, q) => renderViaHTTP(context.appPort, p, q)) diff --git a/test/node_modules/next b/test/node_modules/next new file mode 120000 index 00000000..c25bddb6 --- /dev/null +++ b/test/node_modules/next @@ -0,0 +1 @@ +../.. \ No newline at end of file diff --git a/wallaby.js b/wallaby.js deleted file mode 100644 index dedab25e..00000000 --- a/wallaby.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = function (wallaby) { - return { - files: [ - 'server/**/*.js', - 'client/**/*.js', - 'lib/**/*.js', - 'dist/**/*.js', - 'test/**/*.*', - '!test/**/*.test.js' - ], - - tests: [ - 'test/**/*.test.js', - '!test/integration/**/*.test.js' - ], - - compilers: { - '**/*.js': wallaby.compilers.babel() - }, - - env: { - type: 'node', - runner: 'node', - params: { - env: 'NODE_PATH=test/lib' - } - }, - - testFramework: 'jest' - } -} diff --git a/yarn.lock b/yarn.lock index b9aa4c9a..98bccd3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,51 +2,6 @@ # yarn lockfile v1 -"@semantic-release/commit-analyzer@^3.0.1": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@semantic-release/commit-analyzer/-/commit-analyzer-3.0.7.tgz#dc955444a6d3d2ae9b8e21f90c2c80c4e9142b2f" - dependencies: - "@semantic-release/error" "^2.0.0" - conventional-changelog-angular "^1.4.0" - conventional-commits-parser "^2.0.0" - import-from "^2.1.0" - lodash "^4.17.4" - pify "^3.0.0" - -"@semantic-release/condition-travis@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@semantic-release/condition-travis/-/condition-travis-6.1.0.tgz#7962c728f4c19389b57759c7ff9ee08df9b15795" - dependencies: - "@semantic-release/error" "^2.0.0" - github "^11.0.0" - parse-github-repo-url "^1.4.1" - semver "^5.0.3" - travis-deploy-once "^3.0.0" - -"@semantic-release/error@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@semantic-release/error/-/error-2.0.0.tgz#f156ecd509f5288c48bc7425a8abe22f975d1f8b" - -"@semantic-release/last-release-npm@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@semantic-release/last-release-npm/-/last-release-npm-2.0.2.tgz#c91b1ccb48b0d7095b107be6ebc2c0c08bd88c27" - dependencies: - "@semantic-release/error" "^2.0.0" - npm-registry-client "^8.4.0" - npmlog "^4.0.0" - -"@semantic-release/release-notes-generator@^4.0.0": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@semantic-release/release-notes-generator/-/release-notes-generator-4.0.5.tgz#46cc2f16bdb60fe9674bbcd616bfe0f8bb35347c" - dependencies: - "@semantic-release/error" "^2.0.0" - conventional-changelog-angular "^1.4.0" - conventional-changelog-core "^1.9.0" - get-stream "^3.0.0" - import-from "^2.1.0" - lodash "^4.17.4" - pify "^3.0.0" - "@taskr/babel@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@taskr/babel/-/babel-1.1.0.tgz#f5af6b236395cbd013d3f67328ca73651e0299a1" @@ -75,12 +30,11 @@ dependencies: chokidar "^1.7.0" -JSONStream@^1.0.4: - version "1.3.1" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.1.tgz#707f761e01dae9e16f1bcf93703b78c70966579a" +"@zeit/source-map-support@0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@zeit/source-map-support/-/source-map-support-0.6.0.tgz#3808cbe343ae786a9a5cad06fd5a1aab210baea0" dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" + source-map "^0.6.0" abab@^1.0.3: version "1.0.4" @@ -127,13 +81,6 @@ acorn@^5.0.0, acorn@^5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" -agent-base@2: - version "2.1.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" - dependencies: - extend "~3.0.0" - semver "~5.0.1" - aggregate-error@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-1.0.0.tgz#888344dad0220a72e3af50906117f48771925fac" @@ -149,6 +96,10 @@ ajv-keywords@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.0.tgz#a296e17f7bfae7c1ce4f7e0de53d29cb32162df0" +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + ajv@^4.7.0, ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" @@ -156,6 +107,15 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.0.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.4.tgz#3daf9a8b67221299fdae8d82d117ed8e6c80244b" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + ajv@^5.1.0, ajv@^5.1.5: version "5.2.3" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.3.tgz#c06f598778c44c6b161abafe3466b81ad1814ed2" @@ -228,7 +188,7 @@ append-transform@^0.4.0: dependencies: default-require-extensions "^1.0.0" -aproba@^1.0.3: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -292,18 +252,10 @@ array-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -373,11 +325,11 @@ async@2.0.1: dependencies: lodash "^4.8.0" -async@^1.4.0, async@^1.5.2, async@~1.5.2: +async@^1.4.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" -async@^2.0.0, async@^2.0.1, async@^2.1.2, async@^2.1.4: +async@^2.0.0, async@^2.1.2, async@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" dependencies: @@ -448,7 +400,7 @@ babel-eslint@8.0.1: babel-types "7.0.0-beta.0" babylon "7.0.0-beta.22" -babel-generator@6.26.0, babel-generator@^6.18.0, babel-generator@^6.26.0: +babel-generator@^6.18.0, babel-generator@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" dependencies: @@ -628,14 +580,6 @@ babel-plugin-jest-hoist@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-21.2.0.tgz#2cef637259bd4b628a6cace039de5fcd14dbb006" -babel-plugin-module-resolver@2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-2.7.1.tgz#18be3c42ddf59f7a456c9e0512cd91394f6e4be1" - dependencies: - find-babel-config "^1.0.1" - glob "^7.1.1" - resolve "^1.2.0" - babel-plugin-react-require@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-react-require/-/babel-plugin-react-require-3.0.0.tgz#2e4e7b4496b93a654a1c80042276de4e4eeb20e3" @@ -773,7 +717,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@6.26.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" dependencies: @@ -1150,12 +1094,6 @@ bl@^1.0.0: dependencies: readable-stream "^2.0.5" -bl@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" - dependencies: - readable-stream "~2.0.5" - block-stream@*: version "0.0.9" resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" @@ -1321,9 +1259,23 @@ builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" +cacache@^10.0.1: + version "10.0.2" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.2.tgz#105a93a162bbedf3a25da42e1939ed99ffb145f8" + dependencies: + bluebird "^3.5.0" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^1.3.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.1" + ssri "^5.0.0" + unique-filename "^1.1.0" + y18n "^3.2.1" caching-transform@^1.0.0: version "1.0.1" @@ -1347,21 +1299,10 @@ callsites@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" @@ -1447,6 +1388,10 @@ chokidar@^1.7.0: optionalDependencies: fsevents "^1.0.0" +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + chromedriver@2.32.3: version "2.32.3" resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-2.32.3.tgz#ce84f055bee7cbfe56f31182b276f33256b12bf1" @@ -1525,15 +1470,6 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -codeclimate-test-reporter@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/codeclimate-test-reporter/-/codeclimate-test-reporter-0.5.0.tgz#93fa06b1c18e4117349128dc4e38aad08043828e" - dependencies: - async "~1.5.2" - commander "2.9.0" - lcov-parse "0.0.10" - request "~2.79.0" - color-convert@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" @@ -1550,27 +1486,18 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - commander@^2.9.0: version "2.11.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" -compare-func@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" - dependencies: - array-ify "^1.0.0" - dot-prop "^3.0.0" - compress-commons@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" @@ -1584,7 +1511,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@1.6.0, concat-stream@^1.5.2: +concat-stream@1.6.0, concat-stream@^1.5.0, concat-stream@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1592,13 +1519,6 @@ concat-stream@1.6.0, concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" -config-chain@~1.1.8: - version "1.1.11" - resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.11.tgz#aba09747dfbe4c3e70e766a6e41586e1859fc6f2" - dependencies: - ini "^1.3.4" - proto-list "~1.2.1" - console-browserify@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" @@ -1625,65 +1545,6 @@ content-type@~1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" -conventional-changelog-angular@^1.4.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-1.5.1.tgz#974e73aa1c39c392e4364f2952bd9a62904e9ea3" - dependencies: - compare-func "^1.3.1" - q "^1.4.1" - -conventional-changelog-core@^1.9.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-1.9.2.tgz#a09b6b959161671ff45b93cc9efb0444e7c845c0" - dependencies: - conventional-changelog-writer "^2.0.1" - conventional-commits-parser "^2.0.0" - dateformat "^1.0.12" - get-pkg-repo "^1.0.0" - git-raw-commits "^1.2.0" - git-remote-origin-url "^2.0.0" - git-semver-tags "^1.2.2" - lodash "^4.0.0" - normalize-package-data "^2.3.5" - q "^1.4.1" - read-pkg "^1.1.0" - read-pkg-up "^1.0.1" - through2 "^2.0.0" - -conventional-changelog-writer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-2.0.1.tgz#47c10d0faba526b78d194389d1e931d09ee62372" - dependencies: - compare-func "^1.3.1" - conventional-commits-filter "^1.0.0" - dateformat "^1.0.11" - handlebars "^4.0.2" - json-stringify-safe "^5.0.1" - lodash "^4.0.0" - meow "^3.3.0" - semver "^5.0.1" - split "^1.0.0" - through2 "^2.0.0" - -conventional-commits-filter@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-1.0.0.tgz#6fc2a659372bc3f2339cf9ffff7e1b0344b93039" - dependencies: - is-subset "^0.1.1" - modify-values "^1.0.0" - -conventional-commits-parser@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-2.0.0.tgz#71d01910cb0a99aeb20c144e50f81f4df3178447" - dependencies: - JSONStream "^1.0.4" - is-text-path "^1.0.0" - lodash "^4.2.1" - meow "^3.3.0" - split2 "^2.0.0" - through2 "^2.0.0" - trim-off-newlines "^1.0.0" - convert-source-map@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" @@ -1700,6 +1561,17 @@ cookie@0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" @@ -1708,7 +1580,7 @@ core-js@^2.4.0, core-js@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" -core-util-is@1.0.2, core-util-is@^1.0.1, core-util-is@~1.0.0: +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1852,11 +1724,9 @@ cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": dependencies: cssom "0.3.x" -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - dependencies: - array-find-index "^1.0.1" +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" d@1: version "1.0.0" @@ -1864,12 +1734,6 @@ d@1: dependencies: es5-ext "^0.10.9" -dargs@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" - dependencies: - number-is-nan "^1.0.0" - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1884,36 +1748,29 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -dateformat@^1.0.11, dateformat@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" - dependencies: - get-stdin "^4.0.1" - meow "^3.3.0" - debug-log@^1.0.0, debug-log@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -debug@2, debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - debug@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: ms "0.7.1" +debug@2.6.9, debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + debug@^3.0.1: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: ms "2.0.0" -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: +decamelize@^1.0.0, decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2070,11 +1927,14 @@ domutils@^1.5.1: dom-serializer "0" domelementtype "1" -dot-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" +duplexify@^3.1.2, duplexify@^3.4.2: + version "3.5.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.1.tgz#4e1516be68838bc90a49994f0b39a6e5960befcd" dependencies: - is-obj "^1.0.0" + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" ecc-jsbn@~0.1.1: version "0.1.1" @@ -2124,7 +1984,7 @@ encoding@^0.1.11: dependencies: iconv-lite "~0.4.13" -end-of-stream@^1.0.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" dependencies: @@ -2489,7 +2349,7 @@ express@4.15.5: utils-merge "1.0.0" vary "~1.1.1" -extend@3, extend@~3.0.0, extend@~3.0.1: +extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -2516,7 +2376,7 @@ fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" -fast-levenshtein@~2.0.4: +fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -2595,13 +2455,6 @@ finalhandler@~1.0.6: statuses "~1.3.1" unpipe "~1.0.0" -find-babel-config@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.1.0.tgz#acc01043a6749fec34429be6b64f542ebb5d6355" - dependencies: - json5 "^0.5.1" - path-exists "^3.0.0" - find-cache-dir@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" @@ -2622,6 +2475,12 @@ find-root@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" +find-up@2.1.0, find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -2629,12 +2488,6 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - fkill@5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/fkill/-/fkill-5.1.0.tgz#d07c20a6bee698b02ae727fdcad61fbcdec198b8" @@ -2657,12 +2510,12 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -follow-redirects@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919" +flush-write-stream@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.2.tgz#c81b90d8746766f1a609a46809946c45dd8ae417" dependencies: - debug "^2.2.0" - stream-consume "^0.1.0" + inherits "^2.0.1" + readable-stream "^2.0.4" for-in@^1.0.1: version "1.0.2" @@ -2693,14 +2546,6 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@~1.0.0-rc4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c" - dependencies: - async "^2.0.1" - combined-stream "^1.0.5" - mime-types "^2.1.11" - form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" @@ -2733,13 +2578,21 @@ friendly-errors-webpack-plugin@1.6.1: error-stack-parser "^2.0.0" string-length "^1.0.1" -fs-extra@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b" +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" dependencies: graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" fs.realpath@^1.0.0: version "1.0.0" @@ -2804,20 +2657,6 @@ get-own-enumerable-property-symbols@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz#5c4ad87f2834c4b9b4e84549dc1e0650fb38c24b" -get-pkg-repo@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" - dependencies: - hosted-git-info "^2.1.4" - meow "^3.3.0" - normalize-package-data "^2.3.0" - parse-github-repo-url "^1.3.0" - through2 "^2.0.0" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - get-stdin@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" @@ -2832,63 +2671,6 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -git-head@^1.2.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/git-head/-/git-head-1.20.1.tgz#036d16a4b374949e4e3daf15827903686d3ccd52" - dependencies: - git-refs "^1.1.3" - -git-raw-commits@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-1.2.0.tgz#0f3a8bfd99ae0f2d8b9224d58892975e9a52d03c" - dependencies: - dargs "^4.0.1" - lodash.template "^4.0.2" - meow "^3.3.0" - split2 "^2.0.0" - through2 "^2.0.0" - -git-refs@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/git-refs/-/git-refs-1.1.3.tgz#83097cb3a92585c4a4926ec54e2182df9e20e89d" - dependencies: - path-object "^2.3.0" - slash "^1.0.0" - walk "^2.3.9" - -git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - -git-semver-tags@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-1.2.2.tgz#a2139be1bf6e337e125f3eb8bb8fc6f5d4d6445f" - dependencies: - meow "^3.3.0" - semver "^5.0.1" - -gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - dependencies: - ini "^1.3.2" - -github@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/github/-/github-11.0.0.tgz#edb32df5efb33cad004ebf0bdd2a4b30bb63a854" - dependencies: - follow-redirects "0.0.7" - https-proxy-agent "^1.0.0" - mime "^1.2.11" - netrc "^0.1.4" - -github@~0.1.10: - version "0.1.16" - resolved "https://registry.yarnpkg.com/github/-/github-0.1.16.tgz#895d2a85b0feb7980d89ac0ce4f44dcaa03f17b5" - glob-base@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" @@ -2902,12 +2684,9 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob-promise@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.2.0.tgz#fa53179ef42b7c5a6450e77374ab54c9708b7fe9" - dependencies: - codeclimate-test-reporter "^0.5.0" - semantic-release "^8.0.3" +glob-promise@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.3.0.tgz#d1eb3625c4e6dcbb9b96eeae4425d5a3b135fed2" glob@7.1.2, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2: version "7.1.2" @@ -2966,19 +2745,15 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6: +graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" -handlebars@^4.0.2, handlebars@^4.0.3: +handlebars@^4.0.3: version "4.0.11" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" dependencies: @@ -3097,7 +2872,7 @@ hoek@4.x.x: version "4.2.0" resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" -hoist-non-react-statics@2.3.1: +hoist-non-react-statics@2.3.1, hoist-non-react-statics@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0" @@ -3108,7 +2883,7 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -hosted-git-info@^2.1.4, hosted-git-info@^2.4.2: +hosted-git-info@^2.1.4: version "2.5.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" @@ -3177,14 +2952,6 @@ https-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" -https-proxy-agent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" - dependencies: - agent-base "2" - debug "2" - extend "3" - husky@0.14.3: version "0.14.3" resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" @@ -3205,16 +2972,14 @@ ieee754@^1.1.4: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + ignore@^3.0.9, ignore@^3.2.0: version "3.3.5" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.5.tgz#c4e715455f6073a8d7e5dae72d2fc9d71663dba6" -import-from@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" - dependencies: - resolve-from "^3.0.0" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -3248,7 +3013,7 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@^1.2.0, ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: +ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" @@ -3393,7 +3158,7 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" -is-obj@^1.0.0, is-obj@^1.0.1: +is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -3449,20 +3214,10 @@ is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" -is-subset@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" - is-symbol@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" -is-text-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - dependencies: - text-extensions "^1.0.0" - is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -3858,7 +3613,7 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" @@ -3866,20 +3621,10 @@ json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - optionalDependencies: - graceful-fs "^4.1.6" - jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" -jsonparse@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" @@ -4052,49 +3797,6 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - -lodash._bindcallback@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - -lodash._createassigner@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11" - dependencies: - lodash._bindcallback "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.restparam "^3.0.0" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - -lodash._reinterpolate@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - -lodash.assign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" - dependencies: - lodash._baseassign "^3.0.0" - lodash._createassigner "^3.0.0" - lodash.keys "^3.0.0" - lodash.assignin@^4.0.9: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" @@ -4119,22 +3821,6 @@ lodash.foreach@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - lodash.map@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" @@ -4155,39 +3841,18 @@ lodash.reject@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" -lodash.restparam@^3.0.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - lodash.some@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -lodash.template@^4.0.2: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" - dependencies: - lodash._reinterpolate "~3.0.0" - lodash.templatesettings "^4.0.0" - -lodash.templatesettings@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" - dependencies: - lodash._reinterpolate "~3.0.0" - lodash@4.16.2: version "4.16.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.2.tgz#3e626db827048a699281a8a125226326cfc0e652" -lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1, lodash@^4.8.0: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.8.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lodash@~1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.3.1.tgz#a4663b53686b895ff074e2ba504dfb76a8e2b770" - log-driver@1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" @@ -4221,14 +3886,7 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: dependencies: js-tokens "^3.0.0" -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lru-cache@^4.0.0, lru-cache@^4.0.1: +lru-cache@^4.0.0, lru-cache@^4.0.1, lru-cache@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" dependencies: @@ -4247,10 +3905,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - maximatch@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/maximatch/-/maximatch-0.1.0.tgz#86cd8d6b04c9f307c05a6b9419906d0360fb13a2" @@ -4300,21 +3954,6 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -meow@^3.3.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -4362,7 +4001,7 @@ mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" -mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7: +mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17, mime-types@~2.1.7: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" dependencies: @@ -4372,7 +4011,7 @@ mime@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" -mime@1.4.1, mime@^1.2.11, mime@^1.3.4: +mime@1.4.1, mime@^1.3.4: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" @@ -4404,7 +4043,7 @@ minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: +minimist@1.2.0, minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -4412,6 +4051,21 @@ minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" +mississippi@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-1.3.0.tgz#d201583eb12327e3c5c1642a404a9cacf94e34f5" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^1.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mk-dirs@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mk-dirs/-/mk-dirs-1.0.0.tgz#44ee67f82341c6762718e88e85e577882e1f67fd" @@ -4435,14 +4089,21 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkd dependencies: minimist "0.0.8" -modify-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.0.tgz#e2b6cdeb9ce19f99317a53722f3dbf5df5eaaab2" - moment@^2.11.2: version "2.19.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.1.tgz#56da1a2d1cbf01d38b7e1afc31c10bcfa1929167" +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + mri@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.0.tgz#5c0a3f29c8ccffbbb1ec941dcec09d71fa32f36a" @@ -4491,14 +4152,6 @@ negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" -nerf-dart@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/nerf-dart/-/nerf-dart-1.0.0.tgz#e6dab7febf5ad816ea81cf5c629c5a0ebde72c1a" - -netrc@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" - node-fetch@1.7.3, node-fetch@^1.0.1: version "1.7.3" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" @@ -4562,11 +4215,7 @@ node-pre-gyp@^0.6.36: tar "^2.2.1" tar-pack "^3.4.0" -node-uuid@~1.4.7: - version "1.4.8" - resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" - -nopt@^4.0.0, nopt@^4.0.1: +nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" dependencies: @@ -4579,13 +4228,7 @@ nopt@~1.0.10: dependencies: abbrev "1" -nopt@~3.0.1: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - dependencies: - abbrev "1" - -normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, "normalize-package-data@~1.0.1 || ^2.0.0": +normalize-package-data@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: @@ -4604,38 +4247,12 @@ normalize-path@^2.0.0, normalize-path@^2.0.1: dependencies: remove-trailing-separator "^1.0.1" -"npm-package-arg@^3.0.0 || ^4.0.0 || ^5.0.0": - version "5.1.2" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-5.1.2.tgz#fb18d17bb61e60900d6312619919bd753755ab37" - dependencies: - hosted-git-info "^2.4.2" - osenv "^0.1.4" - semver "^5.1.0" - validate-npm-package-name "^3.0.0" - npm-path@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.3.tgz#15cff4e1c89a38da77f56f6055b24f975dfb2bbe" dependencies: which "^1.2.10" -npm-registry-client@^8.4.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-8.5.0.tgz#4878fb6fa1f18a5dc08ae83acf94d0d0112d7ed0" - dependencies: - concat-stream "^1.5.2" - graceful-fs "^4.1.6" - normalize-package-data "~1.0.1 || ^2.0.0" - npm-package-arg "^3.0.0 || ^4.0.0 || ^5.0.0" - once "^1.3.3" - request "^2.74.0" - retry "^0.10.0" - semver "2 >=2.2.1 || 3.x || 4 || 5" - slide "^1.1.3" - ssri "^4.1.2" - optionalDependencies: - npmlog "2 || ^3.1.0 || ^4.0.0" - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -4650,21 +4267,7 @@ npm-which@^3.0.1: npm-path "^2.0.2" which "^1.2.10" -npmconf@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/npmconf/-/npmconf-2.1.2.tgz#66606a4a736f1e77a059aa071a79c94ab781853a" - dependencies: - config-chain "~1.1.8" - inherits "~2.0.0" - ini "^1.2.0" - mkdirp "^0.5.0" - nopt "~3.0.1" - once "~1.3.0" - osenv "^0.1.0" - semver "2 || 3 || 4" - uid-number "0.0.5" - -"npmlog@2 || ^3.1.0 || ^4.0.0", npmlog@^4.0.0, npmlog@^4.0.2: +npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: @@ -4752,18 +4355,12 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0, once@^1.3.3, once@^1.4.0: +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" -once@~1.3.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" - dependencies: - wrappy "1" - onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -4815,7 +4412,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@^0.1.0, osenv@^0.1.4: +osenv@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" dependencies: @@ -4844,26 +4441,18 @@ p-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" -p-reduce@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" - -p-retry@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-1.0.0.tgz#3927332a4b7d70269b535515117fc547da1a6968" - dependencies: - retry "^0.10.0" - -p-series@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-series/-/p-series-1.0.0.tgz#7ec9e7b4406cc32066298a6f9860e55e91b36e07" - dependencies: - p-reduce "^1.0.0" - pako@~0.2.0: version "0.2.9" resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + parse-asn1@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.0.tgz#37c4f9b7ed3ab65c74817b5f2480937fbf97c712" @@ -4874,10 +4463,6 @@ parse-asn1@^5.0.0: evp_bytestokey "^1.0.0" pbkdf2 "^3.0.3" -parse-github-repo-url@^1.3.0, parse-github-repo-url@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" - parse-glob@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" @@ -4934,13 +4519,6 @@ path-match@1.2.4: http-errors "~1.4.0" path-to-regexp "^1.0.0" -path-object@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/path-object/-/path-object-2.3.0.tgz#03e46653e5c375c60af1cabdd94bc6448a5d9110" - dependencies: - core-util-is "^1.0.1" - lodash.assign "^3.0.0" - path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" @@ -5093,6 +4671,10 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + promise@^7.0.1, promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -5114,10 +4696,6 @@ prop-types@15.6.0, prop-types@^15.5.4, prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" -proto-list@~1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" - proxy-addr@~1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" @@ -5143,6 +4721,21 @@ public-encrypt@^4.0.0: parse-asn1 "^5.0.0" randombytes "^2.0.1" +pump@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b" + dependencies: + duplexify "^3.1.2" + inherits "^2.0.1" + pump "^1.0.0" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -5155,18 +4748,10 @@ q@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" -q@^1.4.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - qs@6.5.0: version "6.5.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49" -qs@~6.2.0: - version "6.2.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" - qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" @@ -5213,38 +4798,35 @@ rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-deep-force-update@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.1.tgz#8ea4263cd6455a050b37445b3f08fd839d86e909" - -react-dom@16.0.0: - version "16.0.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.0.0.tgz#9cc3079c3dcd70d4c6e01b84aab2a7e34c303f58" +react-dom@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044" dependencies: fbjs "^0.8.16" loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.0" -react-hot-loader@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-3.1.1.tgz#e06db8cd0841c41e3ab0b395b2b774126fc8914e" +react-hot-loader@4.0.0-beta.14: + version "4.0.0-beta.14" + resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.0.0-beta.14.tgz#9575065aadda9c53ef455e757b8b36c1fd14e5d6" dependencies: + fast-levenshtein "^2.0.6" global "^4.3.0" - react-deep-force-update "^2.1.1" - react-proxy "^3.0.0-alpha.0" + hoist-non-react-statics "^2.3.1" + react-stand-in "^4.0.0-beta.14" redbox-react "^1.3.6" source-map "^0.6.1" -react-proxy@^3.0.0-alpha.0: - version "3.0.0-alpha.1" - resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-3.0.0-alpha.1.tgz#4400426bcfa80caa6724c7755695315209fa4b07" +react-stand-in@^4.0.0-beta.14: + version "4.0.0-beta.14" + resolved "https://registry.yarnpkg.com/react-stand-in/-/react-stand-in-4.0.0-beta.14.tgz#0a06a94b44bc4ca1d06575414acf400585d84e35" dependencies: - lodash "^4.6.1" + shallowequal "^1.0.2" -react@16.0.0: - version "16.0.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.0.0.tgz#ce7df8f1941b036f02b2cca9dbd0cb1f0e855e2d" +react@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba" dependencies: fbjs "^0.8.16" loose-envify "^1.1.0" @@ -5265,7 +4847,7 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg@^1.0.0, read-pkg@^1.1.0: +read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" dependencies: @@ -5281,7 +4863,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.2.6: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" dependencies: @@ -5293,17 +4875,6 @@ readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable string_decoder "~1.0.3" util-deprecate "~1.0.1" -readable-stream@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - string_decoder "~0.10.x" - util-deprecate "~1.0.1" - readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -5351,13 +4922,6 @@ redbox-react@^1.3.6: prop-types "^15.5.4" sourcemapped-stacktrace "^1.1.6" -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - regenerate@^1.2.1: version "1.3.3" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" @@ -5416,7 +4980,7 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@2.79.0, request@~2.79.0: +request@2.79.0: version "2.79.0" resolved "https://registry.yarnpkg.com/request/-/request-2.79.0.tgz#4dfe5bf6be8b8cdc37fcf93e04b65577722710de" dependencies: @@ -5468,7 +5032,7 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@^2.74.0, request@^2.79.0, request@^2.81.0: +request@^2.79.0, request@^2.81.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -5495,32 +5059,6 @@ request@^2.74.0, request@^2.79.0, request@^2.81.0: tunnel-agent "^0.6.0" uuid "^3.1.0" -request@~2.74.0: - version "2.74.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.74.0.tgz#7693ca768bbb0ea5c8ce08c084a45efa05b892ab" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - bl "~1.1.2" - caseless "~0.11.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~1.0.0-rc4" - har-validator "~2.0.6" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - node-uuid "~1.4.7" - oauth-sign "~0.8.1" - qs "~6.2.0" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "~0.4.1" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5537,10 +5075,6 @@ require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" -require-relative@^0.8.7: - version "0.8.7" - resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" - require-uncached@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -5556,15 +5090,17 @@ resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.2.0: +resolve@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +resolve@^1.1.6: version "1.4.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" dependencies: @@ -5577,10 +5113,6 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" -retry@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - rewrite-imports@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/rewrite-imports/-/rewrite-imports-1.0.0.tgz#a4705c3829006e4f7541bf29d534d8d3b1717c83" @@ -5620,6 +5152,12 @@ run-parallel@^1.1.2: version "1.1.6" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039" +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" @@ -5652,42 +5190,17 @@ sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" -semantic-release@^8.0.3: - version "8.2.1" - resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-8.2.1.tgz#0bd4c2d372b328b2617fb34688937e58387f1bc1" +schema-utils@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.3.tgz#e2a594d3395834d5e15da22b48be13517859458e" dependencies: - "@semantic-release/commit-analyzer" "^3.0.1" - "@semantic-release/condition-travis" "^6.0.0" - "@semantic-release/error" "^2.0.0" - "@semantic-release/last-release-npm" "^2.0.0" - "@semantic-release/release-notes-generator" "^4.0.0" - execa "^0.8.0" - fs-extra "^4.0.2" - git-head "^1.2.1" - github "^11.0.0" - lodash "^4.0.0" - nerf-dart "^1.0.0" - nopt "^4.0.0" - normalize-package-data "^2.3.4" - npmconf "^2.1.2" - npmlog "^4.0.0" - p-series "^1.0.0" - parse-github-repo-url "^1.3.0" - require-relative "^0.8.7" - semver "^5.4.1" + ajv "^5.0.0" + ajv-keywords "^2.1.0" -"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1: +"semver@2 || 3 || 4 || 5", semver@^5.3.0: version "5.4.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" -"semver@2 || 3 || 4": - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - -semver@~5.0.1: - version "5.0.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" - send@0.15.6: version "0.15.6" resolved "https://registry.yarnpkg.com/send/-/send-0.15.6.tgz#20f23a9c925b762ab82705fe2f9db252ace47e34" @@ -5724,6 +5237,10 @@ send@0.16.1: range-parser "~1.2.0" statuses "~1.3.1" +serialize-javascript@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.4.0.tgz#7c958514db6ac2443a8abc062dc9f7886a7f6005" + serve-static@1.12.6: version "1.12.6" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.6.tgz#b973773f63449934da54e5beba5e31d9f4211577" @@ -5756,6 +5273,10 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +shallowequal@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.0.2.tgz#1561dbdefb8c01408100319085764da3fcf83f8f" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -5790,7 +5311,7 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" -slide@^1.1.3, slide@^1.1.5: +slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -5810,7 +5331,7 @@ source-list-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" -source-map-support@0.4.18, source-map-support@^0.4.15: +source-map-support@^0.4.15: version "0.4.18" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" dependencies: @@ -5820,7 +5341,7 @@ source-map@0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -source-map@0.6.1, source-map@^0.6.1: +source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -5865,18 +5386,6 @@ spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" -split2@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" - dependencies: - through2 "^2.0.2" - -split@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - dependencies: - through "2" - sprintf-js@^1.0.3: version "1.1.1" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" @@ -5899,9 +5408,9 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -ssri@^4.1.2: - version "4.1.6" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-4.1.6.tgz#0cb49b6ac84457e7bdd466cb730c3cb623e9a25b" +ssri@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.0.0.tgz#13c19390b606c821f2a10d02b351c1729b94d8cf" dependencies: safe-buffer "^5.1.0" @@ -5950,9 +5459,12 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" -stream-consume@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" stream-http@^2.3.1: version "2.7.2" @@ -5964,6 +5476,10 @@ stream-http@^2.3.1: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + stream-to-observable@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" @@ -6000,7 +5516,7 @@ string-width@^2.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string_decoder@^0.10.25, string_decoder@~0.10.x: +string_decoder@^0.10.25: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -6048,12 +5564,6 @@ strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" @@ -6179,10 +5689,6 @@ test-exclude@^4.1.1: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" -text-extensions@^1.0.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.7.0.tgz#faaaba2625ed746d568a23e4d0aacd9bf08a8b39" - text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -6203,14 +5709,14 @@ throat@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" -through2@^2.0.0, through2@^2.0.2: +through2@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" dependencies: readable-stream "^2.1.5" xtend "~4.0.1" -through@2, "through@>=2.2.7 <3", through@^2.3.6: +through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -6260,32 +5766,6 @@ tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" -travis-ci@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/travis-ci/-/travis-ci-2.1.1.tgz#98696265af827ae3576f31aa06d876e74b4b082e" - dependencies: - github "~0.1.10" - lodash "~1.3.1" - request "~2.74.0" - underscore.string "~2.2.0rc" - -travis-deploy-once@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/travis-deploy-once/-/travis-deploy-once-3.0.0.tgz#079f7c2d56472ef8e87d540c9b108bed9d9e1fdd" - dependencies: - chalk "^2.1.0" - p-retry "^1.0.0" - semver "^5.4.1" - travis-ci "^2.1.1" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - -trim-off-newlines@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" - trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -6333,6 +5813,13 @@ ua-parser-js@^0.7.9: version "0.7.17" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + uglify-js@^2.6, uglify-js@^2.8.29: version "2.8.29" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" @@ -6346,6 +5833,19 @@ uglify-to-browserify@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" +uglifyjs-webpack-plugin@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.6.tgz#f4ba8449edcf17835c18ba6ae99b9d610857fb19" + dependencies: + cacache "^10.0.1" + find-cache-dir "^1.0.0" + schema-utils "^0.4.2" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + uglifyjs-webpack-plugin@^0.4.6: version "0.4.6" resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz#b951f4abb6bd617e66f63eb891498e391763e309" @@ -6354,10 +5854,6 @@ uglifyjs-webpack-plugin@^0.4.6: uglify-js "^2.8.29" webpack-sources "^1.0.1" -uid-number@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.5.tgz#5a3db23ef5dbd55b81fce0ec9a2ac6fccdebb81e" - uid-number@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" @@ -6369,10 +5865,6 @@ underscore.string@3.3.4: sprintf-js "^1.0.3" util-deprecate "^1.0.2" -underscore.string@~2.2.0rc: - version "2.2.1" - resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.2.1.tgz#d7c0fa2af5d5a1a67f4253daee98132e733f0f19" - unfetch@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-3.0.0.tgz#8d1e0513a4ecd0e5ff2d41a6ba77771aae8b6482" @@ -6381,9 +5873,17 @@ uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" -universalify@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" unpipe@~1.0.0: version "1.0.0" @@ -6427,12 +5927,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "~1.0.0" spdx-expression-parse "~1.0.0" -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - dependencies: - builtins "^1.0.3" - vargs@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/vargs/-/vargs-0.1.0.tgz#6b6184da6520cc3204ce1b407cac26d92609ebff" @@ -6455,7 +5949,7 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" -walk@2.3.9, walk@^2.3.9: +walk@2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.9.tgz#31b4db6678f2ae01c39ea9fb8725a9031e558a7b" dependencies: @@ -6517,9 +6011,9 @@ webpack-dev-middleware@1.12.0: range-parser "^1.0.3" time-stamp "^2.0.0" -webpack-hot-middleware@2.19.1: - version "2.19.1" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.19.1.tgz#5db32c31c955c1ead114d37c7519ea554da0d405" +webpack-hot-middleware@2.21.0: + version "2.21.0" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.21.0.tgz#7b3c113a7a4b301c91e0749573c7aab28b414b52" dependencies: ansi-html "0.0.7" html-entities "^1.2.0" @@ -6533,9 +6027,16 @@ webpack-sources@^1.0.1: source-list-map "^2.0.0" source-map "~0.5.3" -webpack@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.6.0.tgz#a89a929fbee205d35a4fa2cc487be9cbec8898bc" +webpack-sources@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.10.0.tgz#5291b875078cf2abf42bdd23afe3f8f96c17d725" dependencies: acorn "^5.0.0" acorn-dynamic-import "^2.0.0" @@ -6616,6 +6117,13 @@ worker-farm@^1.3.1: errno "^0.1.4" xtend "^4.0.1" +worker-farm@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.5.2.tgz#32b312e5dc3d5d45d79ef44acc2587491cd729ae" + dependencies: + errno "^0.1.4" + xtend "^4.0.1" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"