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

Fix development mode output (#6312)

* Remove usage of WebpackBar and Friendly Errors

* Add new clearConsole helper

* Add new simplified output for development mode

* Add an explicit bootstrapping mode

* Add missing returns

* Use existing output style

* Adjust first output to say Waiting on

* Only print URL if present
This commit is contained in:
Joe Haddad 2019-02-16 11:09:49 -05:00 committed by Tim Neutkens
parent 036f5bf11b
commit 56b1f81ace
8 changed files with 208 additions and 93 deletions

View file

@ -4,6 +4,7 @@ import arg from 'arg'
import { existsSync } from 'fs'
import startServer from '../server/lib/start-server'
import { printAndExit } from '../server/lib/utils'
import { startedDevelopmentServer } from '../build/output'
const args = arg({
// Types
@ -55,10 +56,12 @@ if (!existsSync(join(dir, 'pages'))) {
}
const port = args['--port'] || 3000
const appUrl = `http://${args['--hostname'] || 'localhost'}:${port}`
startedDevelopmentServer(appUrl)
startServer({dir, dev: true}, port, args['--hostname'])
.then(async (app) => {
// tslint:disable-next-line
console.log(`> Ready on http://${args['--hostname'] || 'localhost'}:${port}`)
await app.prepare()
})
.catch((err) => {

View file

@ -0,0 +1,13 @@
// This file is derived from Jest:
// https://github.com/facebook/jest/blob/d9d501ac342212b8a58ddb23a31518beb7b56f47/packages/jest-util/src/specialChars.ts#L18
const isWindows = process.platform === 'win32'
const isInteractive = process.stdout.isTTY
export function clearConsole() {
if (!isInteractive) {
return
}
process.stdout.write(isWindows ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H')
}

View file

@ -0,0 +1,110 @@
import createStore from 'unistore'
import { store, OutputState } from './store'
import formatWebpackMessages from '../../client/dev-error-overlay/format-webpack-messages'
export function startedDevelopmentServer(appUrl: string) {
store.setState({ appUrl })
}
let previousClient: any = null
let previousServer: any = null
type WebpackStatus =
| { loading: true }
| {
loading: false
errors: string[] | null
warnings: string[] | null
}
type WebpackStatusStore = {
client: WebpackStatus
server: WebpackStatus
}
enum WebpackStatusPhase {
COMPILING = 1,
COMPILED_WITH_ERRORS = 2,
COMPILED_WITH_WARNINGS = 3,
COMPILED = 4,
}
function getWebpackStatusPhase(status: WebpackStatus): WebpackStatusPhase {
if (status.loading) {
return WebpackStatusPhase.COMPILING
}
if (status.errors) {
return WebpackStatusPhase.COMPILED_WITH_ERRORS
}
if (status.warnings) {
return WebpackStatusPhase.COMPILED_WITH_WARNINGS
}
return WebpackStatusPhase.COMPILED
}
const webpackStore = createStore<WebpackStatusStore>()
webpackStore.subscribe(state => {
const { client, server } = state
const [{ status }] = [
{ status: client, phase: getWebpackStatusPhase(client) },
{ status: server, phase: getWebpackStatusPhase(server) },
].sort((a, b) => a.phase.valueOf() - b.phase.valueOf())
const { bootstrap: bootstrapping, appUrl } = store.getState()
if (bootstrapping && status.loading) {
return
}
let nextStoreState: OutputState = {
bootstrap: false,
appUrl: appUrl!,
...status,
}
store.setState(nextStoreState, true)
})
export function watchCompiler(client: any, server: any) {
if (previousClient === client && previousServer === server) {
return
}
webpackStore.setState({
client: { loading: true },
server: { loading: true },
})
function tapCompiler(
key: string,
compiler: any,
onEvent: (status: WebpackStatus) => void
) {
compiler.hooks.invalid.tap(`NextJsInvalid-${key}`, () => {
onEvent({ loading: true })
})
compiler.hooks.done.tap(`NextJsDone-${key}`, (stats: any) => {
const { errors, warnings } = formatWebpackMessages(
stats.toJson({ all: false, warnings: true, errors: true })
)
onEvent({
loading: false,
errors: errors && errors.length ? errors : null,
warnings: warnings && warnings.length ? warnings : null,
})
})
}
tapCompiler('client', client, status =>
webpackStore.setState({ client: status })
)
tapCompiler('server', server, status =>
webpackStore.setState({ server: status })
)
previousClient = client
previousServer = server
}

View file

@ -0,0 +1,56 @@
import chalk from 'chalk'
import createStore from 'unistore'
import { clearConsole } from './clearConsole'
export type OutputState =
| { bootstrap: true; appUrl: string | null }
| ({ bootstrap: false; appUrl: string | null } & (
| { loading: true }
| {
loading: false
errors: string[] | null
warnings: string[] | null
}))
export const store = createStore<OutputState>({ appUrl: null, bootstrap: true })
store.subscribe(state => {
clearConsole()
if (state.bootstrap) {
console.log(chalk.cyan('Starting the development server ...'))
if (state.appUrl) {
console.log()
console.log(` > Waiting on ${state.appUrl!}`)
}
return
}
if (state.loading) {
console.log('Compiling ...')
return
}
if (state.errors) {
console.log(chalk.red('Failed to compile.'))
console.log()
console.log(state.errors[0])
return
}
if (state.warnings) {
console.log(chalk.yellow('Compiled with warnings.'))
console.log()
console.log(state.warnings.join('\n\n'))
return
}
console.log(chalk.green('Compiled successfully!'))
if (state.appUrl) {
console.log()
console.log(` > Ready on ${state.appUrl!}`)
}
console.log()
console.log('Note that pages will be compiled when you first load them.')
})

View file

@ -2,8 +2,6 @@ import path from 'path'
import webpack from 'webpack'
import resolve from 'resolve'
import CaseSensitivePathPlugin from 'case-sensitive-paths-webpack-plugin'
import FriendlyErrorsWebpackPlugin from 'friendly-errors-webpack-plugin'
import WebpackBar from 'webpackbar'
import NextJsSsrImportPlugin from './webpack/plugins/nextjs-ssr-import'
import NextJsSSRModuleCachePlugin from './webpack/plugins/nextjs-ssr-module-cache'
import NextJsRequireCacheHotReloader from './webpack/plugins/nextjs-require-cache-hot-reloader'
@ -278,10 +276,6 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer
!isServer && new ReactLoadablePlugin({
filename: REACT_LOADABLE_MANIFEST
}),
new WebpackBar({
name: isServer ? 'server' : 'client'
}),
dev && !isServer && new FriendlyErrorsWebpackPlugin(),
// Even though require.cache is server only we have to clear assets from both compilations
// This is because the client compilation generates the build manifest that's used on the server side
dev && new NextJsRequireCacheHotReloader(),

View file

@ -59,13 +59,13 @@
"babel-plugin-transform-react-remove-prop-types": "0.4.15",
"cacache": "^11.0.2",
"case-sensitive-paths-webpack-plugin": "2.1.2",
"chalk": "2.4.2",
"cross-spawn": "5.1.0",
"del": "3.0.0",
"event-source-polyfill": "0.0.12",
"find-cache-dir": "2.0.0",
"find-up": "2.1.0",
"fresh": "0.5.2",
"friendly-errors-webpack-plugin": "1.7.0",
"glob": "7.1.2",
"hoist-non-react-statics": "3.2.0",
"http-status": "1.0.1",
@ -88,12 +88,12 @@
"terser": "3.16.1",
"tty-aware-progress": "1.0.3",
"unfetch": "3.0.0",
"unistore": "3.2.1",
"url": "0.11.0",
"webpack": "4.29.0",
"webpack-dev-middleware": "3.4.0",
"webpack-hot-middleware": "2.24.3",
"webpack-sources": "1.3.0",
"webpackbar": "3.1.4 ",
"worker-farm": "1.5.2",
"ws": "6.1.2"
},

View file

@ -12,6 +12,7 @@ import {route} from 'next-server/dist/server/router'
import globModule from 'glob'
import {promisify} from 'util'
import {createPagesMapping, createEntrypoints} from '../build/entries'
import {watchCompiler} from '../build/output'
const glob = promisify(globModule)
@ -259,6 +260,11 @@ export default class HotReloader {
}
async prepareBuildTools (multiCompiler) {
watchCompiler(
multiCompiler.compilers[0],
multiCompiler.compilers[1]
)
// This plugin watches for changes to _document.js and notifies the client side that it should reload the page
multiCompiler.compilers[1].hooks.done.tap('NextjsHotReloaderForServer', (stats) => {
if (!this.initialized) {

View file

@ -1898,7 +1898,7 @@ ansi-escapes@^1.0.0:
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
integrity sha1-06ioOzGapneTZisT52HHkRQiMG4=
ansi-escapes@^3.0.0, ansi-escapes@^3.1.0:
ansi-escapes@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==
@ -2975,6 +2975,15 @@ chalk@2.4.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@2.4.2, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@ -2995,15 +3004,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
@ -3109,7 +3109,7 @@ chromedriver@2.42.0:
mkdirp "^0.5.1"
request "^2.87.0"
ci-info@^1.5.0, ci-info@^1.6.0:
ci-info@^1.5.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==
@ -3388,17 +3388,6 @@ configstore@3.1.2:
write-file-atomic "^2.0.0"
xdg-basedir "^3.0.0"
consola@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/consola/-/consola-2.3.0.tgz#256b80a927234351d512a4e5693eac9cf8a572b9"
integrity sha512-gsawoQfj4DtnwsaPrabFpFOZBxWpzpT+E9fu6YAdFKO3NvBOOsFcQl/cskDOoIDDLMkLZvm4jjMWvSEelIumIw==
dependencies:
chalk "^2.4.1"
dayjs "^1.7.7"
figures "^2.0.0"
std-env "^2.2.1"
string-width "^2.1.1"
console-browserify@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
@ -3978,11 +3967,6 @@ dateformat@^3.0.0:
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
dayjs@^1.7.7:
version "1.7.8"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.7.8.tgz#05d288f8d4b2140110cc1519cfe317d6f1f11a3c"
integrity sha512-Gp4Y5KWeSri0QOWGzHQz7VrKDkfEpS92dCLK7P8hYowRFbaym1vj3d6CoHio3apSS4KSi/qb5Edemv26IN5Hfg==
debug-log@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f"
@ -4458,13 +4442,6 @@ error-ex@^1.2.0, error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
error-stack-parser@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.2.tgz#4ae8dbaa2bf90a8b450707b9149dcabca135520d"
integrity sha512-E1fPutRDdIj/hohG0UpT5mayXNCxXP9d+snxFsPU9X0XgccOumKraa3juDMwTUyi7+Bu5+mCGagjg4IYeNbOdw==
dependencies:
stackframe "^1.0.4"
es-abstract@^1.5.1, es-abstract@^1.6.1, es-abstract@^1.7.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165"
@ -5365,15 +5342,6 @@ fresh@0.5.2:
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=
friendly-errors-webpack-plugin@1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.0.tgz#efc86cbb816224565861a1be7a9d84d0aafea136"
integrity sha512-K27M3VK30wVoOarP651zDmb93R9zF28usW4ocaK3mfQeIEI5BPht/EzZs5E8QLLwbLRJQMwscAjDxYPb1FuNiw==
dependencies:
chalk "^1.1.3"
error-stack-parser "^2.0.0"
string-width "^2.0.0"
from2@^2.1.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af"
@ -9610,11 +9578,6 @@ pretty-format@^23.6.0:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
pretty-time@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e"
integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==
private@^0.1.6, private@^0.1.8:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
@ -11128,11 +11091,6 @@ stack-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==
stackframe@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.0.4.tgz#357b24a992f9427cba6b545d96a14ed2cbca187b"
integrity sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw==
staged-git-files@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-0.0.4.tgz#d797e1b551ca7a639dec0237dc6eb4bb9be17d35"
@ -11186,13 +11144,6 @@ statuses@~1.4.0:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==
std-env@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/std-env/-/std-env-2.2.1.tgz#2ffa0fdc9e2263e0004c1211966e960948a40f6b"
integrity sha512-IjYQUinA3lg5re/YMlwlfhqNRTzMZMqE+pezevdcTaHceqx8ngEi1alX9nNCk9Sc81fy1fLDeQoaCzeiW1yBOQ==
dependencies:
ci-info "^1.6.0"
stdout-stream@^1.4.0:
version "1.4.1"
resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de"
@ -11979,6 +11930,11 @@ unique-string@^1.0.0:
dependencies:
crypto-random-string "^1.0.0"
unistore@3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/unistore/-/unistore-3.2.1.tgz#26e316c834e39b83b2a301a65f78138f43975a0b"
integrity sha512-102VTsu5dcoADsz+NdBE55JeFh1YYLvrEzLenwE+nu3lFWSVZj2MpvXLkBqrx/YTk+L3kzMG5UwHkHoj/9VcaQ==
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
@ -12296,20 +12252,6 @@ webpack@4.29.0:
watchpack "^1.5.0"
webpack-sources "^1.3.0"
"webpackbar@3.1.4 ":
version "3.1.4"
resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-3.1.4.tgz#7b99fd28bf7c8d4f890b14c042418fc56d0877f0"
integrity sha512-P/ESpzVFl49IL9svoZphf9Kbyh/09vHqo31PP5/fxVrBLCBUHMKbDaWt+Px7zEQZUyFuQCWzRASJHZByQHTdKw==
dependencies:
ansi-escapes "^3.1.0"
chalk "^2.4.1"
consola "^2.3.0"
figures "^2.0.0"
pretty-time "^1.1.0"
std-env "^2.2.1"
text-table "^0.2.0"
wrap-ansi "^4.0.0"
whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
version "1.0.5"
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
@ -12404,15 +12346,6 @@ wrap-ansi@^2.0.0:
string-width "^1.0.1"
strip-ansi "^3.0.1"
wrap-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-4.0.0.tgz#b3570d7c70156159a2d42be5cc942e957f7b1131"
integrity sha512-uMTsj9rDb0/7kk1PbcbCcwvHUxp60fGDB/NNXpVa0Q+ic/e7y5+BwTxKfQ33VYgDppSwi/FBzpetYzo8s6tfbg==
dependencies:
ansi-styles "^3.2.0"
string-width "^2.1.1"
strip-ansi "^4.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"