Skip to content

Commit

Permalink
fix: respect the output.publicPath option for the servecommand (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait authored Dec 30, 2020
1 parent 0595603 commit a3092ef
Show file tree
Hide file tree
Showing 12 changed files with 302 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports[`startDevServer should set default port and host if not provided 1`] = `
Object {
"host": "localhost",
"port": 8080,
"publicPath": "/",
}
`;

Expand All @@ -22,6 +23,7 @@ Object {
"hot": true,
"port": 9000,
"progress": true,
"publicPath": "/",
}
`;

Expand All @@ -40,6 +42,7 @@ Object {
"hot": true,
"port": 9000,
"progress": true,
"publicPath": "/",
}
`;

Expand All @@ -56,6 +59,7 @@ Object {
"host": "localhost",
"port": 9000,
"progress": true,
"publicPath": "/",
}
`;

Expand All @@ -64,6 +68,7 @@ Object {
"host": "localhost",
"port": 9001,
"progress": true,
"publicPath": "/",
}
`;

Expand Down
73 changes: 43 additions & 30 deletions packages/serve/src/startDevServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ import { devServerOptionsType } from './types';
* @returns {Object[]} array of resulting servers
*/
export default async function startDevServer(compiler, cliOptions, logger): Promise<object[]> {
let isDevServer4 = false,
devServerVersion,
Server,
findPort;
let devServerVersion, Server, findPort;

try {
// eslint-disable-next-line node/no-extraneous-require
Expand All @@ -28,24 +25,6 @@ export default async function startDevServer(compiler, cliOptions, logger): Prom
process.exit(2);
}

isDevServer4 = devServerVersion.startsWith('4');

const defaultOpts = {};
const devServerOptions = [];
const compilers = compiler.compilers || [compiler];

compilers.forEach((compiler) => {
if (compiler.options.devServer) {
devServerOptions.push(compiler.options.devServer);
}
});

if (devServerOptions.length === 0) {
devServerOptions.push(defaultOpts);
}

const servers = [];
const usedPorts: number[] = [];
const mergeOptions = (cliOptions: devServerOptionsType, devServerOptions: devServerOptionsType): devServerOptionsType => {
// CLI options should take precedence over devServer options,
// and CLI options should have no default values included
Expand All @@ -60,35 +39,69 @@ export default async function startDevServer(compiler, cliOptions, logger): Prom
return options;
};

for (const devServerOpts of devServerOptions) {
const options = mergeOptions(cliOptions, devServerOpts);
const isMultiCompiler = Boolean(compiler.compilers);

let compilersWithDevServerOption;

if (isMultiCompiler) {
compilersWithDevServerOption = compiler.compilers.filter((compiler) => compiler.options.devServer);

// No compilers found with the `devServer` option, let's use first compiler
if (compilersWithDevServerOption.length === 0) {
compilersWithDevServerOption = [compiler.compilers[0]];
}
} else {
compilersWithDevServerOption = [compiler];
}

const isDevServer4 = devServerVersion.startsWith('4');
const usedPorts = [];
const devServersOptions = [];

for (const compilerWithDevServerOption of compilersWithDevServerOption) {
const options = mergeOptions(cliOptions, compilerWithDevServerOption.options.devServer || {});

if (isDevServer4) {
options.port = await findPort(options.port);
options.client = options.client || {};
options.client.port = options.client.port || options.port;
} else {
if (!options.publicPath) {
options.publicPath =
typeof compilerWithDevServerOption.options.output.publicPath === 'undefined' ||
compilerWithDevServerOption.options.output.publicPath === 'auto'
? '/'
: compilerWithDevServerOption.options.output.publicPath;
}

options.host = options.host || 'localhost';
options.port = options.port || 8080;
}

if (options.port) {
const portNum = +options.port;
const portNumber = Number(options.port);

if (usedPorts.find((port) => portNum === port)) {
if (usedPorts.find((port) => portNumber === port)) {
throw new Error(
'Unique ports must be specified for each devServer option in your webpack configuration. Alternatively, run only 1 devServer config using the --config-name flag to specify your desired config.',
);
}

usedPorts.push(portNum);
usedPorts.push(portNumber);
}

devServersOptions.push({ compiler, options });
}

const servers = [];

for (const devServerOptions of devServersOptions) {
const { compiler, options } = devServerOptions;
const server = new Server(compiler, options);

server.listen(options.port, options.host, (err): void => {
if (err) {
throw err;
server.listen(options.port, options.host, (error): void => {
if (error) {
throw error;
}
});

Expand Down
1 change: 1 addition & 0 deletions packages/serve/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type devServerOptionsType = {
static?: boolean | string | object | (string | object)[];
transportMode?: object | string;
useLocalIp?: boolean;
publicPath?: undefined;
};

type devServerClientOptions = {
Expand Down
13 changes: 13 additions & 0 deletions test/serve/basic/dev-server-output-public-path.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = {
mode: 'development',
devtool: false,
output: {
publicPath: '/my-public-path/',
},
devServer: {
publicPath: '/dev-server-my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false, 'hooks.compilation.taps')],
};
26 changes: 26 additions & 0 deletions test/serve/basic/multi-dev-server-output-public-path.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = [
{
name: 'one',
mode: 'development',
devtool: false,
entry: './src/other.js',
output: {
filename: 'first-output/[name].js',
},
},
{
name: 'two',
mode: 'development',
devtool: false,
output: {
publicPath: '/my-public-path/',
filename: 'second-output/[name].js',
},
devServer: {
publicPath: '/dev-server-my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false, 'hooks.compilation.taps')],
},
];
32 changes: 32 additions & 0 deletions test/serve/basic/multi-dev-server.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const getPort = require('get-port');

const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = async () => [
{
name: 'one',
mode: 'development',
devtool: false,
output: {
filename: 'first-output/[name].js',
},
devServer: {
port: await getPort(),
publicPath: '/one-dev-server-my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false, 'hooks.compilation.taps')],
},
{
name: 'two',
mode: 'development',
devtool: false,
entry: './src/other.js',
output: {
filename: 'second-output/[name].js',
},
devServer: {
port: await getPort(),
publicPath: '/two-dev-server-my-public-path/',
},
},
];
23 changes: 23 additions & 0 deletions test/serve/basic/multi-output-public-path.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = [
{
name: 'one',
mode: 'development',
devtool: false,
output: {
publicPath: '/my-public-path/',
filename: 'first-output/[name].js',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false, 'hooks.compilation.taps')],
},
{
name: 'two',
mode: 'development',
devtool: false,
entry: './src/other.js',
output: {
filename: 'second-output/[name].js',
},
},
];
25 changes: 25 additions & 0 deletions test/serve/basic/multi.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = [
{
name: 'one',
mode: 'development',
devtool: false,
output: {
filename: 'first-output/[name].js',
},
devServer: {
publicPath: '/dev-server-my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false, 'hooks.compilation.taps')],
},
{
name: 'two',
mode: 'development',
devtool: false,
entry: './src/other.js',
output: {
filename: 'second-output/[name].js',
},
},
];
29 changes: 29 additions & 0 deletions test/serve/basic/multiple-dev-server.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = [
{
name: 'one',
mode: 'development',
devtool: false,
output: {
filename: 'first-output/[name].js',
},
devServer: {
publicPath: '/dev-server-my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false)],
},
{
name: 'two',
mode: 'development',
devtool: false,
entry: './src/other.js',
output: {
filename: 'first-output/[name].js',
},
devServer: {
publicPath: '/dev-server-my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false)],
},
];
10 changes: 10 additions & 0 deletions test/serve/basic/output-public-path.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const WebpackCLITestPlugin = require('../../utils/webpack-cli-test-plugin');

module.exports = {
mode: 'development',
devtool: false,
output: {
publicPath: '/my-public-path/',
},
plugins: [new WebpackCLITestPlugin(['mode', 'output'], false, 'hooks.compilation.taps')],
};
Loading

0 comments on commit a3092ef

Please sign in to comment.