Skip to content
This repository has been archived by the owner on Apr 8, 2019. It is now read-only.

Lots of misc #47

Merged
merged 7 commits into from
Mar 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ Type: `Object`

Options for initializing and controlling the server provided.

##### add

Please see [Add-On Features](#add-on-features).

##### compiler

Type: `webpack`
Expand Down Expand Up @@ -269,6 +273,22 @@ Default: `false`
Instruct `webpack-serve` to prepend each line of log output with a `[HH:mm:ss]`
timestamp.

##### on

Type: `Object`
Default: `null`

While running `webpack-serve` from the command line, it can sometimes be useful
to subscribe to events from the module's event bus _within your config_. This
option can be used for that purpose. The option's value must be an `Object`
matching a `key:handler`, `String: Function` pattern. eg:

```js
on: {
'listening': () => { console.log('listening'); }
}
```

##### open

Type: `Boolean|Object`
Expand Down Expand Up @@ -318,7 +338,42 @@ features that those familiar with `webpack-dev-server` have come to rely on. Thi
makes the module far easier to maintain, which ultimately benefits the user.

Luckily, flexibility baked into `webpack-serve` makes it a snap to add-on features.
Listed below are some of the add-on patterns that can be found in
You can leverage this by using the `add` option. The value of the option should
be a `Function` matching the following signature:

```js
add: (app, middleware, options) => {
// ...
}
```

### `add` Function Parameters

- `app` The underlying Koa app
- `middleware` An object containing accessor functions to call both
`webpack-dev-middleware` and the `koa-static` middleware.
- `options` - The internal options object used by `webpack-serve`

Some add-on patterns may require changing the order of middleware used in the
`app`. For instance, if adding routes or using a separate router with the `app`
where routes must be added last, you'll need to call the `middleware` functions
early on. `webpack-serve` recognizes these calls and will not execute them again.
If these calls were omitted, `webpack-serve` would execute both in the default,
last in line, order.

```js
add: (app, middleware, options) => {
// since we're manipulating the order of middleware added, we need to handle
// adding these two internal middleware functions.
middleware.webpack();
middleware.content();

// router *must* be the last middleware added
app.use(router.routes());
}
```

Listed below are some of the add-on patterns and recipes that can be found in
[docs/addons](docs/addons):

- [bonjour](docs/addons/bonjour.config.js)
Expand Down
8 changes: 7 additions & 1 deletion lib/bus.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
'use strict';

const isPlainObject = require('lodash/isPlainObject');
const nanobus = require('nanobus');
const weblog = require('webpack-log');
const WebpackServeError = require('./WebpackServeError');

module.exports = (options) => {
const log = weblog({ name: 'serve', id: 'webpack-serve' });
const bus = nanobus();

if (typeof options.on === 'object') {
if (isPlainObject(options.on)) {
for (const event of Object.keys(options.on)) {
const fn = options.on[event];

if (typeof fn === 'function') {
log.info(`Subscribed to '${event}' event`);
bus.on(event, fn);
} else {
throw new WebpackServeError(`The value for an \`on\` event handler must be a Function. event: ${event}`);
}
}
} else if (options.on) {
throw new WebpackServeError('The value for the `on` option must be an Object. Please see the README.');
}

return bus;
Expand Down
4 changes: 4 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ module.exports = {
toArray(config) {
if (typeof config.entry === 'string') {
config.entry = [config.entry];
} else if (typeof config.entry === 'undefined') {
// webpack v4 defaults an empty config to { entry: './src' }. but since we
// need an array, we'll mimic that default config.
config.entry = ['./src'];
} else if (isPlainObject(config.entry)) {
for (const key of Object.keys(config.entry)) {
const entry = config.entry[key];
Expand Down
5 changes: 1 addition & 4 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ const path = require('path');
const merge = require('lodash/merge');
const weblog = require('webpack-log');
const MultiCompiler = require('webpack/lib/MultiCompiler');
const webpackPackage = require('webpack/package.json');
const { fromFunction } = require('./config');

const webpackVersion = parseInt(webpackPackage.version, 10);

const defaults = {
clipboard: true,
compiler: null,
Expand Down Expand Up @@ -51,7 +48,7 @@ function resolve(options) {

// webpack v4 defaults an empty config to { entry: './src' }. but since we
// need an array, we'll mimic that default config.
if (webpackVersion > 3 && !options.config && (!options.flags || !options.flags.config)) {
if (!options.config && (!options.flags || !options.flags.config)) {
options.config = { entry: ['./src'] };
}

Expand Down
7 changes: 4 additions & 3 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ module.exports = (options) => {
const app = new Koa();
const { bus } = options;
const log = weblog({ name: 'serve', id: 'webpack-serve' });
const uri = `${options.protocol}://${options.host}:${options.port}`;
let http2;
let server;
let koaMiddleware;
Expand Down Expand Up @@ -90,6 +89,8 @@ module.exports = (options) => {
}

server.once('listening', () => {
const uri = `${options.protocol}://${options.host}:${options.port}`;

log.info(chalk`Project is running at {blue ${uri}}`);

if (options.clipboard) {
Expand All @@ -112,8 +113,8 @@ module.exports = (options) => {
});

return Promise.all([
getPort({ port: options.port }),
getPort({ port: options.hot.port || 8081 })
getPort({ port: options.port, host: options.host }),
getPort({ port: options.hot.port || 8081, host: options.host })
])
.then(([port, hotPort]) => {
options.port = port;
Expand Down
49 changes: 24 additions & 25 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions test/fixtures/basic/webpack.function.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const webpack = require('webpack');
// eslint-disable-next-line no-unused-vars
module.exports = function config(env, argv) {
return {
mode: 'development',
context: __dirname,
devtool: 'source-map',
entry: ['./app.js'],
Expand Down
17 changes: 17 additions & 0 deletions test/fixtures/webpack-4-defaults/webpack.no-entry.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

const path = require('path');
const webpack = require('webpack');

module.exports = {
mode: 'development',
context: __dirname,
output: {
filename: './output.js',
path: path.resolve(__dirname)
},
plugins: [
new webpack.NamedModulesPlugin()
],
serve: {}
};
Loading