@berun/runner-webpack
Version:
Webpack runner for building React web applications
156 lines (130 loc) • 4.29 kB
text/typescript
import * as chalk from 'chalk'
import * as clearConsole from 'react-dev-utils/clearConsole'
import * as checkRequiredFiles from 'react-dev-utils/checkRequiredFiles'
import {
choosePort,
createCompiler,
prepareUrls
} from 'react-dev-utils/WebpackDevServerUtils'
import * as openBrowser from 'react-dev-utils/openBrowser'
import { checkBrowsers } from 'react-dev-utils/browsersHelper'
import * as WebpackDevServer from 'webpack-dev-server'
import Berun from '@berun/berun'
import verifyPackageTree from './utils/verifyPackageTree'
const webpack = require('webpack')
// MAIN MODULE EXPORTS, WITH DEFAULT FLOW
export default async (berun: Berun) => {
try {
await taskDevBuildPreFlightArgs(berun)
await taskDevBuildPreFlightChecks(berun)
await taskDevBuildGetPort(berun)
await taskDevBuildCompile(berun)
} catch (err) {
if (err && err.message) {
console.log(err.message)
}
process.exit(1)
}
}
// EXPORT INDIVIDUAL FUNCTIONS FOR MORE FINE-GRAINED CUSTOM TASKS
// SEE @berun/runner-webpack-static for an example of where these are used
export {
taskDevBuildPreFlightArgs,
taskDevBuildPreFlightChecks,
taskDevBuildGetPort,
taskDevBuildCompile
}
async function taskDevBuildPreFlightArgs(berun) {
// Process CLI arguments
const argv = process.argv.slice(2)
berun.sparkyContext.debug = argv.indexOf('--debug') !== -1
berun.sparkyContext.isInteractive = process.stdout.isTTY
}
async function taskDevBuildPreFlightChecks(berun) {
if (process.env.SKIP_PREFLIGHT_CHECK !== 'true') {
verifyPackageTree()
// Warn and crash if required files are missing
if (
!checkRequiredFiles([
// berun.options.paths.appHtml,
berun.options.paths.appIndexJs
])
) {
process.exit(1)
}
}
if (process.env.HOST) {
console.log(
chalk.cyan(
`Attempting to bind to HOST environment variable: ${chalk.yellow(
chalk.bold(process.env.HOST)
)}`
)
)
console.log(
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
)
console.log(
`Learn more here: ${chalk.yellow('http://bit.ly/CRA-advanced-config')}`
)
console.log()
}
// We require that you explictly set browsers and do not fall back to
// browserslist defaults.
await checkBrowsers(berun.options.paths.appPath)
}
async function taskDevBuildGetPort(berun) {
// Tools like Cloud9 rely on this.
const DEFAULT_PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 3000
const HOST = process.env.HOST || '0.0.0.0'
const port = await choosePort(HOST, DEFAULT_PORT)
if (port === null) {
throw new Error('Could not find a suitable port')
}
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'
berun.sparkyContext.url = { protocol, HOST, port }
}
function taskDevBuildCompile(berun) {
const { protocol, HOST, port } = berun.sparkyContext.url
const appName = require(berun.options.paths.appPackageJson).name
const urls = prepareUrls(protocol, HOST, port)
// Serve webpack assets generated by the compiler over a web server.
const serverConfig = berun.devserver.toConfig()
let devServer
const devSocket = {
warnings: warnings =>
devServer.sockWrite(devServer.sockets, 'warnings', warnings),
errors: errors => devServer.sockWrite(devServer.sockets, 'errors', errors)
}
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler({
appName,
config: berun.webpack.toConfig(),
urls,
useYarn: berun.options.paths.useYarn,
webpack,
useTypeScript: false && berun.options.paths.isTypescript,
devSocket
})
devServer = new WebpackDevServer(compiler, serverConfig)
return new Promise((resolve, _) => {
// Launch WebpackDevServer.
devServer.listen(port, HOST, err => {
if (err) {
console.log(err)
return
}
if (berun.sparkyContext.isInteractive) {
clearConsole()
}
console.log(chalk.cyan('Starting the development server...\n'))
openBrowser(urls.localUrlForBrowser)
})
;['SIGINT', 'SIGTERM'].forEach((sig: any) => {
process.on(sig, () => {
devServer.close()
resolve()
})
})
})
}