ko
Version:
build & lint library
149 lines (148 loc) • 5.23 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const webpack_1 = __importDefault(require("webpack"));
const webpack_dev_server_1 = __importDefault(require("webpack-dev-server"));
const webpack_2 = __importDefault(require("../webpack"));
const factory_1 = __importDefault(require("./factory"));
const detect_port_1 = __importDefault(require("detect-port"));
const inquirer_1 = __importDefault(require("inquirer"));
const lodash_1 = require("lodash");
class Dev extends factory_1.default {
constructor(service) {
super(service);
}
get devServerConfig() {
const { serve, publicPath } = this.service.config;
const { host, port, proxy, client = {
overlay: {
errors: true,
warnings: false,
runtimeErrors: true,
},
}, staticPath, historyApiFallback = false, ...others } = serve;
return {
port,
host,
hot: true,
proxy,
client,
static: {
directory: staticPath,
watch: true,
publicPath,
},
setupExitSignals: false,
allowedHosts: 'all',
historyApiFallback,
...others,
};
}
async generateConfig() {
this.webpackConfig = new webpack_2.default(this.service);
const extraConfig = {
devtool: 'cheap-module-source-map',
mode: 'development',
};
const ret = this.webpackConfig.merge(extraConfig, {
devServer: this.devServerConfig,
});
if (ret.plugins) {
const plugins = await this.service.apply({
key: this.service.hookKeySet.WEBPACK_PLUGIN,
context: ret.plugins,
});
ret.plugins = plugins;
}
const { speedUp, disableLazyImports } = this.service.config?.experiment || {};
ret.experiments = {
lazyCompilation: speedUp && disableLazyImports
? {
entries: false,
imports: false,
}
: {
entries: false,
imports: true,
},
};
await this.service.apply({
key: this.service.hookKeySet.MODIFY_WEBPACK,
context: ret,
});
return ret;
}
registerCommand() {
const cmdName = 'dev';
this.service.commander.registerCommand({
name: cmdName,
description: 'start devServer',
options: [
{
flags: '--hash',
description: 'output file name with hash',
},
{
flags: '--analyzer',
description: 'support building analyzer',
},
],
});
this.service.commander.bindAction(cmdName, this.action.bind(this));
}
async changePort(newPort, port) {
const question = {
type: 'confirm',
name: 'changePort',
message: `port: ${port} has been used,use new port ${newPort} instead?`,
default: true,
};
const answer = await inquirer_1.default.prompt([question]);
if (answer.changePort) {
return newPort;
}
this.errorStdout(`so sorry, ${port} already in use!!`);
process.exit(0);
}
async checkPort(port) {
const newPort = await (0, detect_port_1.default)(port);
if (newPort === port) {
return newPort;
}
const isInteractive = process.stdout.isTTY;
if (isInteractive) {
return this.changePort(newPort, port);
}
}
async action(cliOpts) {
process.title = 'ko-dev';
process.env.NODE_ENV = 'development';
this.service.freezeCliOptsWith(cliOpts);
const config = await this.generateConfig();
const serverConfig = (0, lodash_1.omit)(config.devServer, 'compilationSuccessInfo');
const port = serverConfig.port;
const newPort = (await this.checkPort(port));
const compiler = (0, webpack_1.default)(config);
const devServer = new webpack_dev_server_1.default({ ...serverConfig, port: newPort }, compiler);
await devServer.start();
const exitProcess = (callback) => () => {
callback && callback();
process.exit(0);
};
process.stdin.on('end', () => {
devServer.stopCallback(() => {
exitProcess(() => this.successStdout('webpack devServer process exit successfully'));
});
process.stdin.resume();
});
['SIGINT', 'SIGTERM'].forEach(signal => {
process.on(signal, exitProcess(() => {
console.log('\n');
this.warningStdout('stop webpack devServer process via command signal:', signal);
}));
});
}
}
exports.default = Dev;