Skip to content
This repository has been archived by the owner on Feb 18, 2024. It is now read-only.

Clean up dev-server options #1175

Merged
merged 1 commit into from
Oct 15, 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
14 changes: 13 additions & 1 deletion docs/migration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,20 @@ to RHL v4 while installing it into your project also.
- **BREAKING CHANGE** `@neutrinojs/web`, `@neutrinojs/node`, and their dependent presets no longer configure
defaults for copying static files at build time [#814](https://github.com/neutrinojs/neutrino/pull/814).
Use the `@neutrinojs/copy` middleware to configure this for v9.
- **BREAKING CHANGE** `@neutrinojs/dev-server` (used by `@neutrinojs/web`) no longer sets `contentBase`
- **BREAKING CHANGE** `@neutrinojs/dev-server` (used by `@neutrinojs/web`) no longer sets
[contentBase](https://webpack.js.org/configuration/dev-server/#devserver-contentbase)
by default, meaning that in development any files that are not part of the webpack build need to be
explicitly included (such as by importing from JS or using `@neutrinojs/copy`) or they will not be
accessible from the dev server [#1165](https://github.com/neutrinojs/neutrino/pull/1165).
This prevents missing files from only being discovered once in production.
- **BREAKING CHANGE** `@neutrinojs/dev-server` no longer sets
[public](https://webpack.js.org/configuration/dev-server/#devserver-public) or
[host](https://webpack.js.org/configuration/dev-server/#devserver-host), meaning that
for certain workflows (such as running webpack-dev-server behind a proxy) you may need to set
them yourself. In particular, due to a bug in the previous implementation, the dev server
used to be accessible on all network interfaces, whereas it is now correctly only available
over localhost. As such if running webpack-dev-server from within a Docker container or VM,
you will now need to set `host` to `0.0.0.0` to allow connections from the host machine.
- **BREAKING CHANGE** When using `@neutrinojs/web` and presets that depend on it,
source maps must now be configured using the preset's `devtool` option rather than
manually in a later middleware, to ensure that `terser-webpack-plugin` is configured
Expand Down Expand Up @@ -265,6 +274,9 @@ for setting these properties as strings is still supported. This also introduces
entry point property on `neutrino.options.mains` now returns a normalized object, even when using string options.
- **BREAKING CHANGE** When configuring webpack with a target of `node` the `@neutrinojs/jest` preset will default its
`testEnvironment` to also be `node` instead of `jsdom` [#1030](https://github.com/neutrinojs/neutrino/pull/1030).
- **BREAKING CHANGE** `@neutrinojs/web` no longer supports the shorthand of `devServer.proxy`
being set to a string [#1175](https://github.com/neutrinojs/neutrino/pull/1175). Instead pass an
object using the [options here](https://webpack.js.org/configuration/dev-server/#devserver-proxy).
- **BREAKING CHANGE** `@neutrinojs/web` and its dependent middleware no longer have the `options.hotEntries` option
[#902](https://github.com/neutrinojs/neutrino/pull/902).
- **BREAKING CHANGE** `@neutrinojs/web` and its dependent middleware no longer include `worker-loader` for automatically
Expand Down
44 changes: 9 additions & 35 deletions packages/dev-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Yarn v1.2.1+, or npm v5.4+
- Neutrino 9
- webpack 4
- webpack-dev-server 3

## Installation

Expand Down Expand Up @@ -42,27 +43,15 @@ neutrino.use(devServer);

// Usage with custom options (default options are shown)
neutrino.use(devServer, {
https: false,
port: 5000,
host: 'localhost',
public: 'localhost:5000',
hot: true,
// Redirect 404s to index.html, so that apps that use the HTML 5 History API work.
historyApiFallback: true,
publicPath: '/',
headers: {
host: 'localhost:5000'
},
// Only display compile duration and errors/warnings, to reduce noise when rebuilding.
stats: {
assets: false,
children: false,
chunks: false,
colors: true,
all: false,
errors: true,
hash: false,
modules: false,
publicPath: false,
timings: false,
version: false,
timings: true,
warnings: true
}
});
Expand All @@ -80,27 +69,15 @@ module.exports = {
module.exports = {
use: [
['@neutrinojs/dev-server', {
https: false,
port: 5000,
host: 'localhost',
public: 'localhost:5000',
hot: true,
// Redirect 404s to index.html, so that apps that use the HTML 5 History API work.
historyApiFallback: true,
publicPath: '/',
headers: {
host: 'localhost'
},
// Only display compile duration and errors/warnings, to reduce noise when rebuilding.
stats: {
assets: false,
children: false,
chunks: false,
colors: true,
all: false,
errors: true,
hash: false,
modules: false,
publicPath: false,
timings: false,
version: false,
timings: true,
warnings: true
}
}]
Expand All @@ -112,9 +89,6 @@ By default this middleware will start a development server with Hot Module Repla
`http://localhost:5000`. To enable HMR with your application, read the documentation of corresponding Neutrino
preset or middleware.

It is recommended to call this middleware only in development mode when `process.env.NODE_ENV === 'development'`.
Copy link
Member Author

@edmorley edmorley Oct 13, 2018

Choose a reason for hiding this comment

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

Now that the @neutrinojs/dev-server preset only sets the devServer option, there's no real reason why the middleware shouldn't always be used.

More information about usage of Neutrino middleware can be found in the [documentation](https://neutrinojs.org/middleware/).

## Middleware options

`@neutrinojs/dev-server` optionally accepts an object with several options to override the default behavior.
Expand Down
60 changes: 14 additions & 46 deletions packages/dev-server/index.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,16 @@
const merge = require('deepmerge');

const isLocal = host => host === 'localhost' || host === '127.0.0.1';
const getHost = publicHost => (isLocal(publicHost) ? 'localhost' : '0.0.0.0');
const getPort = opts => opts.port || 5000;
const getPublic = options => {
const port = getPort(options);

if (options.public) {
const normalizedPath = options.public.split(':');

return normalizedPath.length === 2
? options.public
: `${normalizedPath[0]}:${port}`;
}

return !options.host || isLocal(options.host)
? `localhost:${port}`
: `${options.host}:${port}`;
};

module.exports = (neutrino, opts = {}) => {
const port = getPort(opts);
const publicHost = getPublic(opts);
const host = getHost(publicHost);

neutrino.config.devServer.merge(merge.all([
{
port,
https: false,
hot: true,
historyApiFallback: true,
publicPath: '/',
headers: {
host: publicHost
},
// Only display compile duration and errors/warnings, to reduce noise when rebuilding.
stats: {
all: false,
errors: true,
timings: true,
warnings: true
}
module.exports = (neutrino, options = {}) => {
neutrino.config.devServer.merge({
port: 5000,
hot: true,
// Redirect 404s to index.html, so that apps that use the HTML 5 History API work.
historyApiFallback: true,
// Only display compile duration and errors/warnings, to reduce noise when rebuilding.
stats: {
all: false,
errors: true,
timings: true,
warnings: true
},
opts,
{ host, public: publicHost }
]));
...options
});
};
6 changes: 2 additions & 4 deletions packages/dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,9 @@
"npm": ">=5.4.0",
"yarn": ">=1.2.1"
},
"dependencies": {
"deepmerge": "^1.5.2"
},
"peerDependencies": {
"neutrino": "^9.0.0-0",
"webpack": "^4.0.0"
"webpack": "^4.0.0",
"webpack-dev-server": "^3.0.0"
}
}
2 changes: 1 addition & 1 deletion packages/preact/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ use the [@neutrinojs/copy](https://neutrinojs.org/packages/copy/) preset alongsi
## Paths

The `@neutrinojs/preact` preset loads assets relative to the path of your application by setting webpack's
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `./`. If you wish to load
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `''`. If you wish to load
assets instead from a CDN, or if you wish to change to an absolute path for your application, customize your build to
override `output.publicPath`. See the [Customizing](#customizing) section below.

Expand Down
2 changes: 1 addition & 1 deletion packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ use the [@neutrinojs/copy](https://neutrinojs.org/packages/copy/) preset alongsi
## Paths

The `@neutrinojs/web` preset loads assets relative to the path of your application by setting webpack's
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `./`. If you wish to load
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `''`. If you wish to load
assets instead from a CDN, or if you wish to change to an absolute path for your application, customize your build to
override `output.publicPath`. See the [Customizing](#customizing) section below.

Expand Down
2 changes: 1 addition & 1 deletion packages/vue/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ use the [@neutrinojs/copy](https://neutrinojs.org/packages/copy/) preset alongsi
## Paths

The `@neutrinojs/web` preset loads assets relative to the path of your application by setting webpack's
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `./`. If you wish to load
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `''`. If you wish to load
assets instead from a CDN, or if you wish to change to an absolute path for your application, customize your build to
override `output.publicPath`. See the [Customizing](#customizing) section below.

Expand Down
31 changes: 7 additions & 24 deletions packages/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ use the [@neutrinojs/copy](https://neutrinojs.org/packages/copy/) preset alongsi
## Paths

The `@neutrinojs/web` preset loads assets relative to the path of your application by setting webpack's
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `./`. If you wish to load
[`output.publicPath`](https://webpack.js.org/configuration/output/#output-publicpath) to `''`. If you wish to load
assets instead from a CDN, or if you wish to change to an absolute path for your application, customize your build to
override `output.publicPath`. See the [Customizing](#customizing) section below.

Expand All @@ -180,10 +180,9 @@ module.exports = {
// Enables Hot Module Replacement. Set to false to disable
hot: true,

// Sets webpack's `output.publicPath` and
// `devServer.publicPath` settings. Useful if you want to
// serve assets from a non-root location (e.g. `/assets/`)
publicPath: './',
// Sets webpack's `output.publicPath` setting, which is useful if you
// want to serve assets from a non-root location (e.g. `/assets/`).
publicPath: '',

// Change options for @neutrinojs/style-loader
style: {
Expand Down Expand Up @@ -325,41 +324,25 @@ Or to set default values, use the object form:

### Dev Server Proxy

If you are handling requests with a server, you may want to set up a proxy for development. See webpack's [`devServer.proxy`](https://webpack.js.org/configuration/dev-server/#devserver-proxy) for all available options.

Optionally, you may pass a url string (instead of an object) to `devServer.proxy`.
This will proxy **all requests** through the given url, and set some sensible defaults.
If you are handling requests with a server, you may want to set up a proxy for development.
See webpack's [`devServer.proxy`](https://webpack.js.org/configuration/dev-server/#devserver-proxy)
for all available options.

For example:

```js
['@neutrinojs/web', {
devServer: {
proxy: 'http://localhost:3000'
}
}]
```

Is equivalent to:

```js
['@neutrinojs/web', {
devServer: {
proxy: {
'**': {
target: 'http://localhost:3000',
changeOrigin: true,
headers: {
'X-Dev-Server-Proxy': 'http://localhost:3000'
}
}
}
}
}]
```

The `X-Dev-Server-Proxy` header can be useful for detecting if your existing app is being requested through the proxy.

### Source Maps

By default, the `'cheap-module-eval-source-map'` source map is enabled when `NODE_ENV` is `'development'`, `'source-map'` for `'test'` and no source maps for `'production'`.
Expand Down
27 changes: 10 additions & 17 deletions packages/web/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ const htmlTemplate = require('@neutrinojs/html-template');
const clean = require('@neutrinojs/clean');
const loaderMerge = require('@neutrinojs/loader-merge');
const devServer = require('@neutrinojs/dev-server');
const { resolve } = require('url');
const merge = require('deepmerge');
const { ConfigurationError } = require('neutrino/errors');

Expand All @@ -22,9 +21,8 @@ module.exports = (neutrino, opts = {}) => {
}

const isProduction = process.env.NODE_ENV === 'production';
const publicPath = opts.publicPath || './';
const options = merge({
publicPath,
publicPath: '',
env: false,
hot: true,
html: {},
Expand All @@ -34,8 +32,7 @@ module.exports = (neutrino, opts = {}) => {
test: 'source-map'
},
devServer: {
hot: opts.hot !== false,
publicPath: resolve('/', publicPath)
hot: opts.hot !== false
},
style: {
hot: opts.hot !== false,
Expand Down Expand Up @@ -85,6 +82,14 @@ module.exports = (neutrino, opts = {}) => {
);
}

if (typeof options.devServer.proxy === 'string') {
throw new ConfigurationError(
'The shorthand of setting `devServer.proxy` to a string is no longer supported. ' +
'Use an object and the options listed here instead: ' +
'https://webpack.js.org/configuration/dev-server/#devserver-proxy'
);
}

if (typeof options.devtool === 'string' || typeof options.devtool === 'boolean') {
options.devtool = {
development: options.devtool,
Expand All @@ -93,18 +98,6 @@ module.exports = (neutrino, opts = {}) => {
};
}

if (typeof options.devServer.proxy === 'string') {
options.devServer.proxy = {
'**': {
target: options.devServer.proxy,
changeOrigin: true,
headers: {
Forwarded: 'by=_webpack-dev-server'
}
}
};
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we include the headers bit in our example? If not here, perhaps a page in the docs for "Using Neutrino with Existing SSR Architecture" would make sense.

Copy link
Member Author

@edmorley edmorley Oct 15, 2018

Choose a reason for hiding this comment

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

I think we could easily write several pages on how to set up SSR. Multiple other parts of the webpack config needs adjusting, eg I'm pretty sure html-webpack-plugin doesn't fully work with it out of the box and needs some experimental options enabled.

I think this example is perhaps best aimed at the more common case of "I have a standard SPA but it uses a backend and I want to proxy to it in development". (Not that it precludes adding a more advanced SSR guide somewhere else in the future)

Copy link
Member Author

@edmorley edmorley Oct 15, 2018

Choose a reason for hiding this comment

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

Also, perhaps an SSR guide is best suited as an extra page in webpack's docs? Ultimately Neutrino is not meant to be a replacement for all of webpack/...'s documentation, but a very thin layer of abstraction that assists with configuration generation, sets some sensible defaults, and that makes it easy to mentally map between a webpack guide and how to add that configuration via .neutrinorc.js or via a custom Neutrino preset.

Copy link
Contributor

Choose a reason for hiding this comment

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

#1177 :)

Copy link
Member Author

@edmorley edmorley Oct 15, 2018

Choose a reason for hiding this comment

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

I think we could easily write several pages on how to set up SSR

I underestimated how many pages...!
https://ssr.vuejs.org/

Copy link
Contributor

Choose a reason for hiding this comment

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

Also: it's really 2 different things if you're talking about SSR with React/Vue vs. using webpack/neutrino for "assets", and something else for SSR of html (PHP, Ruby, etc)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah true

// Force @babel/preset-env default behavior (.browserslistrc)
if (options.targets === false) {
options.targets = {};
Expand Down
Loading