Remove cross-spawn (#6450)

This commit is contained in:
Connor Davis 2019-02-26 14:57:32 -06:00 committed by GitHub
parent 967542cc83
commit 7dc50f3867
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 315 additions and 348 deletions

View file

@ -69,6 +69,7 @@
"chromedriver": "2.42.0",
"clone": "2.1.1",
"coveralls": "3.0.2",
"cross-spawn": "6.0.5",
"eslint": "5.4.0",
"eslint-plugin-typescript": "0.14.0",
"express": "4.16.3",

View file

@ -1490,12 +1490,7 @@ You can pass any node arguments to `next` CLI command.
```bash
NODE_OPTIONS="--throw-deprecation" next
NODE_OPTIONS="-r esm" next
```
`--inspect` is a special case since it binds to a port and can't double-bind to the child process the `next` CLI creates.
```
next start --inspect
NODE_OPTIONS="--inspect" next
```
### Customizing webpack config

View file

@ -1,51 +0,0 @@
#!/usr/bin/env node
import { resolve, join } from 'path'
import { existsSync } from 'fs'
import arg from 'arg'
import build from '../build'
import { printAndExit } from '../server/lib/utils'
const args = arg({
// Types
'--help': Boolean,
// Aliases
'-h': '--help',
})
if (args['--help']) {
printAndExit(`
Description
Compiles the application for production deployment
Usage
$ next build <dir>
<dir> represents where the compiled dist folder should go.
If no directory is provided, the dist folder will be created in the current directory.
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration, otherwise it will be created inside '.next'
`, 0)
}
const dir = resolve(args._[0] || '.')
// Check if the provided directory exists
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}
// Check if the pages directory exists
if (!existsSync(join(dir, 'pages'))) {
// Check one level down the tree to see if the pages directory might be there
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
}
printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
}
build(dir)
.catch((err) => {
// tslint:disable-next-line
console.error('> Build error occurred')
printAndExit(err)
})

View file

@ -1,87 +0,0 @@
#!/usr/bin/env node
import { resolve, join } from 'path'
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
'--help': Boolean,
'--port': Number,
'--hostname': String,
// Aliases
'-h': '--help',
'-p': '--port',
'-H': '--hostname',
})
if (args['--help']) {
// tslint:disable-next-line
console.log(`
Description
Starts the application in development mode (hot-code reloading, error
reporting, etc)
Usage
$ next dev <dir> -p <port number>
<dir> represents where the compiled folder should go.
If no directory is provided, the folder will be created in the current directory.
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration.
Options
--port, -p A port number on which to start the application
--hostname, -H Hostname on which to start the application
--help, -h Displays this message
`)
process.exit(0)
}
const dir = resolve(args._[0] || '.')
// Check if pages dir exists and warn if not
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}
if (!existsSync(join(dir, 'pages'))) {
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
}
printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
}
const port = args['--port'] || 3000
const appUrl = `http://${args['--hostname'] || 'localhost'}:${port}`
startedDevelopmentServer(appUrl)
startServer({dir, dev: true}, port, args['--hostname'])
.then(async (app) => {
await app.prepare()
})
.catch((err) => {
if (err.code === 'EADDRINUSE') {
let errorMessage = `Port ${port} is already in use.`
const pkgAppPath = require('find-up').sync('package.json', {
cwd: dir,
})
const appPackage = require(pkgAppPath)
if (appPackage.scripts) {
const nextScript = Object.entries(appPackage.scripts).find((scriptLine) => scriptLine[1] === 'next')
if (nextScript) {
errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p <some other port>\`.`
}
}
// tslint:disable-next-line
console.error(errorMessage)
} else {
// tslint:disable-next-line
console.error(err)
}
process.nextTick(() => process.exit(1))
})

View file

@ -1,70 +0,0 @@
#!/usr/bin/env node
import { resolve, join } from 'path'
import { existsSync } from 'fs'
import arg from 'arg'
import exportApp from '../export'
import { printAndExit } from '../server/lib/utils'
const args = arg({
// Types
'--help': Boolean,
'--silent': Boolean,
'--outdir': String,
'--threads': Number,
'--concurrency': Number,
// Aliases
'-h': '--help',
'-s': '--silent',
'-o': '--outdir',
})
if (args['--help']) {
// tslint:disable-next-line
console.log(`
Description
Exports the application for production deployment
Usage
$ next export [options] <dir>
<dir> represents where the compiled dist folder should go.
If no directory is provided, the 'out' folder will be created in the current directory.
Options
-h - list this help
-o - set the output dir (defaults to 'out')
-s - do not print any messages to console
`)
process.exit(0)
}
const dir = resolve(args._[0] || '.')
// Check if pages dir exists and warn if not
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}
if (!existsSync(join(dir, 'pages'))) {
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
}
printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
}
const options = {
silent: args['--silent'] || false,
threads: args['--threads'],
concurrency: args['--concurrency'],
outdir: args['--outdir'] ? resolve(args['--outdir']) : join(dir, 'out'),
}
exportApp(dir, options)
.then(() => {
printAndExit('Export successful', 0)
})
.catch((err) => {
printAndExit(err)
})

View file

@ -1,54 +0,0 @@
#!/usr/bin/env node
import { resolve } from 'path'
import arg from 'arg'
import startServer from '../server/lib/start-server'
const args = arg({
// Types
'--help': Boolean,
'--port': Number,
'--hostname': String,
// Aliases
'-h': '--help',
'-p': '--port',
'-H': '--hostname',
})
if (args['--help']) {
// tslint:disable-next-line
console.log(`
Description
Starts the application in production mode.
The application should be compiled with \`next build\` first.
Usage
$ next start <dir> -p <port>
<dir> is the directory that contains the compiled dist folder
created by running \`next build\`.
If no directory is provided, the current directory will be assumed.
You can set a custom dist folder in config https://github.com/zeit/next.js#custom-configuration
Options
--port, -p A port number on which to start the application
--hostname, -H Hostname on which to start the application
--help, -h Displays this message
`)
process.exit(0)
}
const dir = resolve(args._[0] || '.')
const port = args['--port'] || 3000
startServer({dir}, port, args['--hostname'])
.then(async (app) => {
// tslint:disable-next-line
console.log(`> Ready on http://${args['--hostname'] || 'localhost'}:${port}`)
await app.prepare()
})
.catch((err) => {
// tslint:disable-next-line
console.error(err)
process.exit(1)
})

View file

@ -1,6 +1,4 @@
#!/usr/bin/env node
import { join } from 'path'
import spawn from 'cross-spawn'
import arg from 'arg'
['react', 'react-dom'].forEach((dependency) => {
@ -14,12 +12,13 @@ import arg from 'arg'
})
const defaultCommand = 'dev'
const commands = [
'build',
'start',
'export',
defaultCommand,
]
export type cliCommand = (argv?: string[]) => void
const commands: {[command: string]: () => Promise<cliCommand>} = {
build: async () => await import('../cli/next-build').then((i) => i.nextBuild),
start: async () => await import('../cli/next-start').then((i) => i.nextStart),
export: async () => await import('../cli/next-export').then((i) => i.nextExport),
dev: async () => await import('../cli/next-dev').then((i) => i.nextDev),
}
const args = arg({
// Types
@ -42,7 +41,7 @@ if (args['--version']) {
}
// Check if we are running `next <subcommand>` or `next`
const foundCommand = commands.includes(args._[0])
const foundCommand = Boolean(commands[args._[0]])
// Makes sure the `next <subcommand> --help` case is covered
// This help message is only showed for `next --help`
@ -53,7 +52,7 @@ if (!foundCommand && args['--help']) {
$ next <command>
Available commands
${commands.join(', ')}
${Object.keys(commands).join(', ')}
Options
--version, -p Version number
@ -66,16 +65,11 @@ if (!foundCommand && args['--help']) {
process.exit(0)
}
const nodeArguments: string[] = []
if (args['--inspect']) {
// tslint:disable-next-line
console.log('Passing "--inspect" to Node.js')
nodeArguments.push('--inspect')
}
const command = foundCommand ? args._[0] : defaultCommand
const forwardedArgs = foundCommand ? args._.slice(1) : args._
if (args['--inspect']) throw new Error(`Use env variable NODE_OPTIONS instead: NODE_OPTIONS="--inspect" next ${command}`)
// Make sure the `next <subcommand> --help` case is covered
if (args['--help']) {
forwardedArgs.push('--help')
@ -84,43 +78,7 @@ if (args['--help']) {
const defaultEnv = command === 'dev' ? 'development' : 'production'
process.env.NODE_ENV = process.env.NODE_ENV || defaultEnv
const bin = join(__dirname, 'next-' + command)
const startProcess = () => {
const proc = spawn('node', [...nodeArguments, bin, ...forwardedArgs], { stdio: 'inherit' })
proc.on('close', (code, signal) => {
if (code !== null) {
process.exit(code)
}
if (signal) {
if (signal === 'SIGKILL') {
process.exit(137)
}
// tslint:disable-next-line
console.log(`got signal ${signal}, exiting`)
process.exit(signal === 'SIGINT' || signal === 'SIGTERM' ? 0 : 1)
}
process.exit(0)
})
proc.on('error', (err) => {
// tslint:disable-next-line
console.error(err)
process.exit(1)
})
return proc
}
let proc = startProcess()
function wrapper() {
if (proc) {
proc.kill()
}
}
process.on('SIGINT', wrapper)
process.on('SIGTERM', wrapper)
process.on('exit', wrapper)
commands[command]().then((exec) => exec(forwardedArgs))
if (command === 'dev') {
const {CONFIG_FILE} = require('next-server/constants')
@ -128,11 +86,7 @@ if (command === 'dev') {
watchFile(`${process.cwd()}/${CONFIG_FILE}`, (cur: any, prev: any) => {
if (cur.size > 0 || prev.size > 0) {
// tslint:disable-next-line
console.log(`\n> Found a change in ${CONFIG_FILE}, restarting the server...`)
// Don't listen to 'close' now since otherwise parent gets killed by listener
proc.removeAllListeners('close')
proc.kill()
proc = startProcess()
console.log(`\n> Found a change in ${CONFIG_FILE}. Restart the server to see the changes in effect.`)
}
})
}

56
packages/next/cli/next-build.ts Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env node
import { resolve, join } from 'path'
import { existsSync } from 'fs'
import arg from 'arg'
import build from '../build'
import { printAndExit } from '../server/lib/utils'
import { cliCommand } from '../bin/next'
const nextBuild: cliCommand = (argv) => {
const args = arg({
// Types
'--help': Boolean,
// Aliases
'-h': '--help',
}, { argv })
if (args['--help']) {
printAndExit(`
Description
Compiles the application for production deployment
Usage
$ next build <dir>
<dir> represents where the compiled dist folder should go.
If no directory is provided, the dist folder will be created in the current directory.
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration, otherwise it will be created inside '.next'
`, 0)
}
const dir = resolve(args._[0] || '.')
// Check if the provided directory exists
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}
// Check if the pages directory exists
if (!existsSync(join(dir, 'pages'))) {
// Check one level down the tree to see if the pages directory might be there
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
}
printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
}
build(dir)
.catch((err) => {
// tslint:disable-next-line
console.error('> Build error occurred')
printAndExit(err)
})
}
export { nextBuild }

92
packages/next/cli/next-dev.ts Executable file
View file

@ -0,0 +1,92 @@
#!/usr/bin/env node
import { resolve, join } from 'path'
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'
import { cliCommand } from '../bin/next'
const nextDev: cliCommand = (argv) => {
const args = arg({
// Types
'--help': Boolean,
'--port': Number,
'--hostname': String,
// Aliases
'-h': '--help',
'-p': '--port',
'-H': '--hostname',
}, { argv })
if (args['--help']) {
// tslint:disable-next-line
console.log(`
Description
Starts the application in development mode (hot-code reloading, error
reporting, etc)
Usage
$ next dev <dir> -p <port number>
<dir> represents where the compiled folder should go.
If no directory is provided, the folder will be created in the current directory.
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration.
Options
--port, -p A port number on which to start the application
--hostname, -H Hostname on which to start the application
--help, -h Displays this message
`)
process.exit(0)
}
const dir = resolve(args._[0] || '.')
// Check if pages dir exists and warn if not
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}
if (!existsSync(join(dir, 'pages'))) {
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
}
printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
}
const port = args['--port'] || 3000
const appUrl = `http://${args['--hostname'] || 'localhost'}:${port}`
startedDevelopmentServer(appUrl)
startServer({dir, dev: true}, port, args['--hostname'])
.then(async (app) => {
await app.prepare()
})
.catch((err) => {
if (err.code === 'EADDRINUSE') {
let errorMessage = `Port ${port} is already in use.`
const pkgAppPath = require('find-up').sync('package.json', {
cwd: dir,
})
const appPackage = require(pkgAppPath)
if (appPackage.scripts) {
const nextScript = Object.entries(appPackage.scripts).find((scriptLine) => scriptLine[1] === 'next')
if (nextScript) {
errorMessage += `\nUse \`npm run ${nextScript[0]} -- -p <some other port>\`.`
}
}
// tslint:disable-next-line
console.error(errorMessage)
} else {
// tslint:disable-next-line
console.error(err)
}
process.nextTick(() => process.exit(1))
})
}
export { nextDev }

View file

@ -0,0 +1,75 @@
#!/usr/bin/env node
import { resolve, join } from 'path'
import { existsSync } from 'fs'
import arg from 'arg'
import exportApp from '../export'
import { printAndExit } from '../server/lib/utils'
import { cliCommand } from '../bin/next'
const nextExport: cliCommand = (argv) => {
const args = arg({
// Types
'--help': Boolean,
'--silent': Boolean,
'--outdir': String,
'--threads': Number,
'--concurrency': Number,
// Aliases
'-h': '--help',
'-s': '--silent',
'-o': '--outdir',
}, { argv })
if (args['--help']) {
// tslint:disable-next-line
console.log(`
Description
Exports the application for production deployment
Usage
$ next export [options] <dir>
<dir> represents where the compiled dist folder should go.
If no directory is provided, the 'out' folder will be created in the current directory.
Options
-h - list this help
-o - set the output dir (defaults to 'out')
-s - do not print any messages to console
`)
process.exit(0)
}
const dir = resolve(args._[0] || '.')
// Check if pages dir exists and warn if not
if (!existsSync(dir)) {
printAndExit(`> No such directory exists as the project root: ${dir}`)
}
if (!existsSync(join(dir, 'pages'))) {
if (existsSync(join(dir, '..', 'pages'))) {
printAndExit('> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?')
}
printAndExit('> Couldn\'t find a `pages` directory. Please create one under the project root')
}
const options = {
silent: args['--silent'] || false,
threads: args['--threads'],
concurrency: args['--concurrency'],
outdir: args['--outdir'] ? resolve(args['--outdir']) : join(dir, 'out'),
}
exportApp(dir, options)
.then(() => {
printAndExit('Export successful', 0)
})
.catch((err) => {
printAndExit(err)
})
}
export { nextExport }

59
packages/next/cli/next-start.ts Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env node
import { resolve } from 'path'
import arg from 'arg'
import startServer from '../server/lib/start-server'
import { cliCommand } from '../bin/next'
const nextStart: cliCommand = (argv) => {
const args = arg({
// Types
'--help': Boolean,
'--port': Number,
'--hostname': String,
// Aliases
'-h': '--help',
'-p': '--port',
'-H': '--hostname',
}, { argv })
if (args['--help']) {
// tslint:disable-next-line
console.log(`
Description
Starts the application in production mode.
The application should be compiled with \`next build\` first.
Usage
$ next start <dir> -p <port>
<dir> is the directory that contains the compiled dist folder
created by running \`next build\`.
If no directory is provided, the current directory will be assumed.
You can set a custom dist folder in config https://github.com/zeit/next.js#custom-configuration
Options
--port, -p A port number on which to start the application
--hostname, -H Hostname on which to start the application
--help, -h Displays this message
`)
process.exit(0)
}
const dir = resolve(args._[0] || '.')
const port = args['--port'] || 3000
startServer({dir}, port, args['--hostname'])
.then(async (app) => {
// tslint:disable-next-line
console.log(`> Ready on http://${args['--hostname'] || 'localhost'}:${port}`)
await app.prepare()
})
.catch((err) => {
// tslint:disable-next-line
console.error(err)
process.exit(1)
})
}
export { nextStart }

View file

@ -60,7 +60,6 @@
"cacache": "^11.0.2",
"case-sensitive-paths-webpack-plugin": "2.1.2",
"chalk": "2.4.2",
"cross-spawn": "5.1.0",
"find-cache-dir": "2.0.0",
"find-up": "2.1.0",
"fresh": "0.5.2",

View file

@ -19,7 +19,7 @@ const babelOpts = {
}
export async function compile (task) {
await task.parallel(['bin', 'server', 'nextbuild', 'nextbuildstatic', 'pages', 'lib', 'client'])
await task.parallel(['cli', 'bin', 'server', 'nextbuild', 'nextbuildstatic', 'pages', 'lib', 'client'])
}
export async function bin (task, opts) {
@ -27,6 +27,11 @@ export async function bin (task, opts) {
notify('Compiled binaries')
}
export async function cli (task, opts) {
await task.source(opts.src || 'cli/**/*.+(js|ts|tsx)').typescript({ module: 'commonjs' }).target('dist/cli')
notify('Compiled cli files')
}
export async function lib (task, opts) {
await task.source(opts.src || 'lib/**/*.+(js|ts|tsx)').typescript({ module: 'commonjs' }).target('dist/lib')
notify('Compiled lib files')

View file

@ -40,13 +40,6 @@ describe('CLI Usage', () => {
})
expect(output.stdout).toMatch(new RegExp(`Next\\.js v${pkg.version.replace(/\./g, '\\.')}`))
})
test('--inspect', async () => {
const output = await runNextCommand(['build', dir, '--inspect'], {
stdout: true
})
expect(output.stdout).toMatch(/Passing "--inspect" to Node\.js/)
})
})
describe('build', () => {
test('--help', async () => {

View file

@ -3744,12 +3744,14 @@ cross-spawn-async@^2.1.1:
lru-cache "^4.0.0"
which "^1.2.8"
cross-spawn@5.1.0, cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
dependencies:
lru-cache "^4.0.1"
nice-try "^1.0.4"
path-key "^2.0.1"
semver "^5.5.0"
shebang-command "^1.2.0"
which "^1.2.9"
@ -3769,14 +3771,12 @@ cross-spawn@^4.0.2:
lru-cache "^4.0.1"
which "^1.2.9"
cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
cross-spawn@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
dependencies:
nice-try "^1.0.4"
path-key "^2.0.1"
semver "^5.5.0"
lru-cache "^4.0.1"
shebang-command "^1.2.0"
which "^1.2.9"