Skip to content

[NEXT]: webpack-cli serve refactor draft #1011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4ee4d41
fix(cli): missing package, fixed function call
knagaitsev Jul 26, 2019
83a27e7
cli(serve): started working on draft serve cli refactor
knagaitsev Jul 28, 2019
25071ce
fix(serve): add newline at helper end
knagaitsev Jul 29, 2019
ab862d2
feat(cli): make serve use webpack cli compiler
knagaitsev Jul 31, 2019
ce8f284
fix(cli): await external command execution, fix lint
knagaitsev Aug 1, 2019
46ca4de
feat(serve): add all flags, improve args parsing
knagaitsev Aug 2, 2019
18636c3
fix(serve): fix gitignore, fix lint problems
knagaitsev Aug 2, 2019
4668ea7
feat(serve): pass socket or port if no socket
knagaitsev Aug 2, 2019
5f1cb74
misc(serve): add newlines at end of files
knagaitsev Aug 8, 2019
89f94f5
misc(serve): removed unwanted js files
knagaitsev Aug 19, 2019
f6381d1
chore(cli): updated package lock
knagaitsev Aug 19, 2019
28d303b
feat(cli): add helper to check if arg is the command name or alias
knagaitsev Aug 19, 2019
1ddcf4a
chore(serve): update package lock
knagaitsev Aug 20, 2019
ed50ac1
misc(serve): change description of command and update snapshot
knagaitsev Aug 20, 2019
786c5c0
cli(dev-server): handle host, port, and socket options and defaults
knagaitsev Aug 22, 2019
b29ec8f
chore(serve): updated dev server and fixed newline problem
knagaitsev Aug 23, 2019
f580b8f
chore(serve): made dev server optional peer dep
knagaitsev Sep 2, 2019
a713c47
misc(serve): change async await and use includes for args
knagaitsev Sep 11, 2019
b681514
cli(bootstrap): change helper functions slightly and fix style
knagaitsev Sep 22, 2019
c13f05b
misc(serve): moved dev server flags temporarily to lib folder
knagaitsev Sep 22, 2019
9da9db4
chore(cli): fix helper to use includes for dashed flag stripping
knagaitsev Sep 25, 2019
7e38b31
chore(serve): allow js in serve package
knagaitsev Sep 25, 2019
6568984
style(serve): make args to camel case helper hyphen based filename
knagaitsev Sep 26, 2019
4ba468b
style(bootstrap): return early and remove else from helper
knagaitsev Sep 26, 2019
3c92b0a
chore(serve): remove allowjs from tsconfig
knagaitsev Sep 26, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions lib/bootstrap.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
const webpackCli = require('./webpack-cli');
const WebpackCLI = require('./webpack-cli');
const { core, commands } = require('./utils/cli-flags');
const cmdArgs = require('command-line-args');

require('./utils/process-log');

const isFlagPresent = (args, flag) => args.find(arg => [flag, `--${flag}`].includes(arg));
const stripDashedFlags = (args, cmd) => args.slice(2).filter(arg => ~arg.indexOf('--') && arg !== cmd.name && arg !== cmd.alias);
const isArgCommandName = (arg, cmd) => arg === cmd.name || arg === cmd.alias;
const stripDashedFlags = (args, cmd) => args.filter(arg => !arg.includes('--') && !isArgCommandName(arg, cmd));
const normalizeFlags = (args, cmd) => {
const slicedArgs = args.slice(2);
if (cmd.name === 'serve') {
return slicedArgs.filter(arg => !isArgCommandName(arg, cmd));
}
return stripDashedFlags(slicedArgs, cmd);
};

const isCommandUsed = commands =>
commands.find(cmd => {
Expand All @@ -27,7 +35,7 @@ async function runCLI(cli, commandIsUsed) {

if (commandIsUsed) {
commandIsUsed.defaultOption = true;
args = stripDashedFlags(process.argv, commandIsUsed);
args = normalizeFlags(process.argv, commandIsUsed);
return await cli.runCommand(commandIsUsed, ...args);
} else {
try {
Expand All @@ -41,8 +49,7 @@ async function runCLI(cli, commandIsUsed) {
if (err.name === 'UNKNOWN_VALUE') {
process.cliLogger.error(`Parse Error (unknown argument): ${err.value}`);
return;
}
else if (err.name === 'ALREADY_SET') {
} else if (err.name === 'ALREADY_SET') {
const argsMap = {};
const keysToDelete = [];
process.argv.forEach((arg, idx) => {
Expand Down Expand Up @@ -74,9 +81,6 @@ async function runCLI(cli, commandIsUsed) {
}
}

// eslint-disable-next-line space-before-function-paren
(async () => {
const commandIsUsed = isCommandUsed(commands);
const cli = new webpackCli();
runCLI(cli, commandIsUsed);
})();
const commandIsUsed = isCommandUsed(commands);
const cli = new WebpackCLI();
runCLI(cli, commandIsUsed);
4 changes: 0 additions & 4 deletions lib/commands/external.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ class ExternalCommand {
if (!pkgLoc) {
pkgLoc = await ExternalCommand.promptInstallation(scopeName, name);
}
// Serve needs to be checked for
if (name === 'serve') {
return pkgLoc ? require(pkgLoc).serve(args) : null;
}
return pkgLoc ? require(pkgLoc).default(args) : null;
}
}
Expand Down
6 changes: 6 additions & 0 deletions lib/utils/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ module.exports = {
type: String,
description: 'Outputs information about your system and dependencies',
},
{
name: 'serve',
scope: 'external',
type: String,
description: 'Run the webpack Dev Server',
},
],
core: [
{
Expand Down
12 changes: 10 additions & 2 deletions lib/utils/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ function compilerCallback(compiler, err, stats, lastHash, options, outputOptions
}
}

module.exports = async function webpackInstance(opts, shouldUseMem) {
function getCompiler(opts) {
return webpack(opts.options);
}

async function webpackInstance(opts, shouldUseMem) {
const { outputOptions, processingErrors, options } = opts;
if (outputOptions.color) {
require('supports-color').stdout;
Expand All @@ -122,7 +126,8 @@ module.exports = async function webpackInstance(opts, shouldUseMem) {
if (processingErrors.length > 0) {
throw new Error(processingErrors);
}
const compiler = await webpack(options);

const compiler = await getCompiler(opts);
let lastHash = null;

const ProgressPlugin = webpack.ProgressPlugin;
Expand Down Expand Up @@ -197,3 +202,6 @@ module.exports = async function webpackInstance(opts, shouldUseMem) {
return await invokeCompilerInstance(compiler, lastHash, options, outputOptions);
}
};

module.exports.getCompiler = getCompiler;
module.exports.webpackInstance = webpackInstance;
193 changes: 193 additions & 0 deletions lib/utils/dev-server-flags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
const CONFIG_GROUP = 'Config options:';
const ADVANCED_GROUP = 'Advanced options:';
const DISPLAY_GROUP = 'Stats options:';
const SSL_GROUP = 'SSL options:';
const CONNECTION_GROUP = 'Connection options:';
const RESPONSE_GROUP = 'Response options:';
const BASIC_GROUP = 'Basic options:';

module.exports = {
devServer: [
{
name: 'bonjour',
type: Boolean,
describe: 'Broadcasts the server via ZeroConf networking on start',
},
{
name: 'lazy',
type: Boolean,
describe: 'Lazy',
},
{
name: 'liveReload',
type: Boolean,
defaultValue: true,
describe: 'Enables/Disables live reloading on changing files',
},
{
name: 'serveIndex',
type: Boolean,
describe: 'Enables/Disables serveIndex middleware',
defaultValue: true,
},
{
name: 'inline',
type: Boolean,
defaultValue: true,
describe:
'Inline mode (set to false to disable including client scripts like livereload)',
},
{
name: 'profile',
type: Boolean,
describe: 'Print compilation profile data for progress steps',
},
{
name: 'progress',
type: Boolean,
describe: 'Print compilation progress in percentage',
group: BASIC_GROUP,
},
{
name: 'hot-only',
type: Boolean,
describe: 'Do not refresh page if HMR fails',
group: ADVANCED_GROUP,
},
{
name: 'stdin',
type: Boolean,
describe: 'close when stdin ends',
},
{
name: 'open',
type: String,
describe: 'Open the default browser, or optionally specify a browser name',
},
{
name: 'useLocalIp',
type: Boolean,
describe: 'Open default browser with local IP',
},
{
name: 'open-page',
type: String,
describe: 'Open default browser with the specified page',
},
{
name: 'client-log-level',
type: String,
group: DISPLAY_GROUP,
defaultValue: 'info',
describe:
'Log level in the browser (trace, debug, info, warn, error or silent)',
},
{
name: 'https',
type: Boolean,
group: SSL_GROUP,
describe: 'HTTPS',
},
{
name: 'http2',
type: Boolean,
group: SSL_GROUP,
describe: 'HTTP/2, must be used with HTTPS',
},
{
name: 'key',
type: String,
describe: 'Path to a SSL key.',
group: SSL_GROUP,
},
{
name: 'cert',
type: String,
describe: 'Path to a SSL certificate.',
group: SSL_GROUP,
},
{
name: 'cacert',
type: String,
describe: 'Path to a SSL CA certificate.',
group: SSL_GROUP,
},
{
name: 'pfx',
type: String,
describe: 'Path to a SSL pfx file.',
group: SSL_GROUP,
},
{
name: 'pfx-passphrase',
type: String,
describe: 'Passphrase for pfx file.',
group: SSL_GROUP,
},
{
name: 'content-base',
type: String,
describe: 'A directory or URL to serve HTML content from.',
group: RESPONSE_GROUP,
},
{
name: 'watch-content-base',
type: Boolean,
describe: 'Enable live-reloading of the content-base.',
group: RESPONSE_GROUP,
},
{
name: 'history-api-fallback',
type: Boolean,
describe: 'Fallback to /index.html for Single Page Applications.',
group: RESPONSE_GROUP,
},
{
name: 'compress',
type: Boolean,
describe: 'Enable gzip compression',
group: RESPONSE_GROUP,
},
// findPort is currently not set up
{
name: 'port',
type: Number,
describe: 'The port',
group: CONNECTION_GROUP,
},
{
name: 'disable-host-check',
type: Boolean,
describe: 'Will not check the host',
group: CONNECTION_GROUP,
},
{
name: 'socket',
type: String,
describe: 'Socket to listen',
group: CONNECTION_GROUP,
},
{
name: 'public',
type: String,
describe: 'The public hostname/ip address of the server',
group: CONNECTION_GROUP,
},
{
name: 'host',
type: String,
describe: 'The hostname/ip address the server will bind to',
group: CONNECTION_GROUP,
},
// use command-line-args "multiple" option, allowing the usage: --allowed-hosts host1 host2 host3
// instead of the old, comma-separated syntax: --allowed-hosts host1,host2,host3
{
name: 'allowed-hosts',
type: String,
describe:
'A list of hosts that are allowed to access the dev server, separated by spaces',
group: CONNECTION_GROUP,
multiple: true,
},
],
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @Loonride it is very very very bad, next PR will change a lot of options, we don't need this do in webpack-cli

20 changes: 15 additions & 5 deletions lib/webpack-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const Compiler = require('./utils/compiler');

const webpackMerge = require('webpack-merge');

class webpackCLI extends GroupHelper {
class WebpackCLI extends GroupHelper {
constructor() {
super();
this.groupMap = new Map();
Expand Down Expand Up @@ -103,12 +103,22 @@ class webpackCLI extends GroupHelper {
return require('./utils/zero-config')(groupResult, isDevMode);
}

async run(args, yargsOptions) {
async processArgs(args, yargsOptions) {
await this.setMappedGroups(args, yargsOptions);
await this.resolveGroups();
let groupResult = await this.runOptionGroups();
groupResult = this.checkDefaults(groupResult);
const webpack = await Compiler(groupResult, this.shouldUseMem);
return groupResult;
}

async getCompiler(args, yargsOptions) {
const groupResult = await this.processArgs(args, yargsOptions);
return await Compiler.getCompiler(groupResult);
}

async run(args, yargsOptions) {
const groupResult = await this.processArgs(args, yargsOptions);
const webpack = await Compiler.webpackInstance(groupResult, this.shouldUseMem);
return webpack;
}

Expand All @@ -121,7 +131,7 @@ class webpackCLI extends GroupHelper {
} else if (command.name === 'plugin') {
command.name = 'generate-plugin';
}
return require('./commands/external').run(command.name, ...args);
return await require('./commands/external').run(command.name, ...args);
}

runHelp() {
Expand All @@ -136,4 +146,4 @@ class webpackCLI extends GroupHelper {

}

module.exports = webpackCLI;
module.exports = WebpackCLI;
5 changes: 0 additions & 5 deletions packages/generators/types/json-loader.d.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/serve/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.js.map
*.js
31 changes: 31 additions & 0 deletions packages/serve/args-to-camel-case.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
*
* Converts dash-seperated strings to camel case
*
* @param {String} str - the string to convert
*
* @returns {String} - new camel case string
*/
function dashesToCamelCase(str): string {
return str.replace(/-([a-z])/g, (g): string => g[1].toUpperCase());
}

/**
*
* Converts CLI args to camel case from dash-separated words
*
* @param {Object} args - argument object parsed by command-line-args
*
* @returns {Object} - the same args object as passed in, with new keys
*/
export default function argsToCamelCase(args): object {
Object.keys(args).forEach((key): void => {
const newKey = dashesToCamelCase(key);
if (key !== newKey) {
const arg = args[key];
delete args[key];
args[newKey] = arg;
}
});
return args;
}
Loading