Skip to content

Commit

Permalink
feat(webpack-dev-server): Support only version 4 of webpack-dev-server
Browse files Browse the repository at this point in the history
BREAKING CHANGE: webpack-dev-server version 4 is now required
BREAKING CHANGE: The config layout is now the same as if webpack-dev-server is used without grunt
BREAKING CHANGE: `port` and `static.directory` are not set by default anymore
BREAKING CHANGE: the `keepalive` option does not exist anymore for the webpack-dev-server task
  • Loading branch information
danez committed Nov 6, 2021
1 parent 7b94ef3 commit 4d4bbf0
Show file tree
Hide file tree
Showing 14 changed files with 2,689 additions and 2,688 deletions.
152 changes: 96 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@

<h2 align="center">Requirements</h2>

- Version 4 of `grunt-webpack` supports webpack version 4 and 5.
- Version 3.2.0 of `webpack-dev-server` is needed if used (optional).
- Version 5 of `grunt-webpack` supports webpack version 4 and 5 and (optional) `webpack-dev-server` version 4.

<h2 align="center">Install</h2>

Expand Down Expand Up @@ -56,43 +55,35 @@ module.exports = function(grunt) {
<h2 align="center">Configuration</h2>

`webpack-grunt` offers two different tasks `webpack` and `webpack-dev-server`. Both support all webpack options as
can be seen in the [webpack documentation][3]. For exceptions and additions see this list.
can be seen in the [webpack documentation][webpack-config]. For exceptions and additions see this list.

### Both Tasks

#### progress

Type: `bool`
Default: `true` (`false` if no TTY present)

Activates or deactivates the progress output of webpack.

#### keepalive
Type: `bool`
Default: `false` (`true` if watch mode is used and for `webpack-dev-server` task)

When set to true the grunt process/task will be kept alive after webpack task is finished. This is especially useful for `watch` and `webpack-dev-server` as these usually need to run as long as not manually killed.

### Webpack Task

#### watch
Type: `bool`
Default: `undefined`
#### failOnError

> Turn on watch mode. This means that after the initial build, webpack will continue to watch for changes in any of the resolved files.
Type: `bool`
Default: `true` (`false` if watch mode is used)

Turning on watch mode also sets the following defaults:
Will terminate the grunt process when an error happens if set to `true`. If set to `false` the grunt process will not be immediately terminated on error and instead continue to run.

- Default `cache` to `true`
- Default `keepalive` to `true`
- Default `failOnError` to `false`
#### keepalive

#### failOnError
Type: `bool`
Default: `true` (`false` if watch mode is used)
Default: `false` (`true` if watch mode is used and for `webpack-dev-server` task)

Will terminate the grunt process when an error happens if set to `true`. If set to `false` the grunt process will not be immediately terminated on error and instead continue to run.
When set to true the grunt process/task will be kept alive after webpack task is finished. This is especially useful for `watch` and `webpack-dev-server` as these usually need to run as long as not manually killed.

#### storeStatsTo

Type: `string`
Default: `null`

Expand All @@ -108,11 +99,28 @@ storeStatsTo: "webpackStats"
...
```

> For more information about grunt template tags have a look at the [grunt docs][2].
> For more information about grunt template tags have a look at the [grunt docs][grunt-template].
#### watch

Type: `bool`
Default: `undefined`

> Turn on watch mode. This means that after the initial build, webpack will continue to watch for changes in any of the resolved files.
Turning on watch mode also sets the following defaults:

- Default `cache` to `true`
- Default `keepalive` to `true`
- Default `failOnError` to `false`

### Webpack-dev-server Task

The webpack-dev-server options [`host`][5], [`hotOnly`][6], [`inline`][1], [`port`][4] and [`public`][7] which are usually only available in the CLI can also be used in this grunt-plugin.
There are no special options for this task. Some changed defaults for WebpackDevServer options are:

| Name | default value |
| -------------- | ------------- |
| devServer.host | localhost |

<h2 align="center">Examples</h2>

Expand All @@ -123,25 +131,25 @@ The webpack-dev-server options [`host`][5], [`hotOnly`][6], [`inline`][1], [`por
This is a simple example that requires the webpack config from the config file.
It also disables stats in non 'development' environments and enables watch in development.

``` javascript
const webpackConfig = require('./webpack.config.js');
```javascript
const webpackConfig = require("./webpack.config.js");

module.exports = function(grunt) {
module.exports = function (grunt) {
grunt.initConfig({
webpack: {
options: {
stats: !process.env.NODE_ENV || process.env.NODE_ENV === 'development'
stats: !process.env.NODE_ENV || process.env.NODE_ENV === "development",
},
prod: webpackConfig,
dev: Object.assign({ watch: true }, webpackConfig)
}
dev: Object.assign({ watch: true }, webpackConfig),
},
});

grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks("grunt-webpack");
};
```

> The webpack task in this example has two targets called `prod` and `dev`. They can be renamed to everything besides `options`. See the [grunt docs][8] for more information about targets.
> The webpack task in this example has two targets called `prod` and `dev`. They can be renamed to everything besides `options`. See the [grunt docs][grunt-targets] for more information about targets.
On the command line you can then do the following.

Expand All @@ -156,16 +164,16 @@ On the command line you can then do the following.
> grunt webpack
```

> For more examples and information have a look at the [webpack documentation][9] which mostly also applies here besides the noted differences above.
> For more examples and information have a look at the [webpack documentation][webpack-start] which mostly also applies here besides the noted differences above.
#### Lazy config loading

In some cases you might want to load the webpack config lazy. This can be done by specifying a function as the config value. The first paramter to this function will be the complete grunt config, which can be used in cases where grunt templates do not work (see below).

```js
const webpackConfig = require('./webpack.config.js');
const webpackConfig = require("./webpack.config.js");

module.exports = function(grunt) {
module.exports = function (grunt) {
grunt.initConfig({
webpack: {
myconfig: () => ({
Expand All @@ -178,7 +186,7 @@ module.exports = function(grunt) {
},
});

grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks("grunt-webpack");
};
```

Expand All @@ -189,9 +197,9 @@ grunt-webpack supports grunt templates in all string values in it's configuratio
In the next example we use a template for `output.filename`.

```js
const webpackConfig = require('./webpack.config.js');
const webpackConfig = require("./webpack.config.js");

module.exports = function(grunt) {
module.exports = function (grunt) {
grunt.initConfig({
outputFileName: "output.js",
webpack: {
Expand All @@ -205,21 +213,21 @@ module.exports = function(grunt) {
},
});

grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks("grunt-webpack");
};
```

For plugins we cannot support grunt template interpolation, as plugins are class instances which we cannot modify during runtime without breaking them. If you need to use template in a string option to a plugin, you can use lazy config loading and use the supplied config. You can also use grunt inside directly to access utility methods:

```js
const webpackConfig = require('./webpack.config.js');
const webpackConfig = require("./webpack.config.js");

module.exports = function(grunt) {
module.exports = function (grunt) {
grunt.initConfig({
name: "Webpack",
pkg: {
copyright: '<%= name %>',
version: '6.55.345',
copyright: "<%= name %>",
version: "6.55.345",
},
webpack: {
myconfig: (config) => ({
Expand All @@ -230,18 +238,56 @@ module.exports = function(grunt) {
},
plugins: [
new webpack.BannerPlugin({
banner: `/*! ${config.pkg.copyright} - Version ${config.pkg.version} dated ${grunt.template.today()} */`,
banner: `/*! ${config.pkg.copyright} - Version ${
config.pkg.version
} dated ${grunt.template.today()} */`,
raw: true,
}),
],
}),
},
});

grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks("grunt-webpack");
};
```

### Webpack-dev-server

#### imported config

This is a simple example that requires the webpack config from the config file.
It also disables stats in non 'development' environments and enables watch in development.

```javascript
const webpackConfig = require("./webpack.config.js");

module.exports = function (grunt) {
grunt.initConfig({
"webpack-dev-server": {
dev: webpackConfig,
},
});

grunt.loadNpmTasks("grunt-webpack");
};
```

> The webpack-dev-server task in this example has one target called `dev`. They can be renamed to everything besides `options`. See the [grunt docs][grunt-targets] for more information about targets.
On the command line you can then do the following.

```bash

# Run webpack-dev-server with the `dev` target
> grunt webpack-dev-server:dev

# Run webpack for all possible targets
> grunt webpack-dev-server
```

> For more examples and information have a look at the [webpack documentation]5] which mostly also applies here besides the noted differences above.
<h2 align="center">Troubleshooting</h2>

### Circular reference detected (.plugins)
Expand All @@ -252,16 +298,16 @@ This is not a bug in the plugin and is totally fine for webpack, but sadly grunt
To workaround this problem use lazy config loading, by wrapping your config inside a function.

```js
const webpackConfig = require('./webpack.config.js');
const webpackConfig = require("./webpack.config.js");

module.exports = function(grunt) {
module.exports = function (grunt) {
grunt.initConfig({
webpack: {
myconfig: () => webpackConfig,
},
});

grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks("grunt-webpack");
};
```

Expand Down Expand Up @@ -304,15 +350,9 @@ module.exports = function(grunt) {
<tbody>
</table>

[1]: https://webpack.js.org/configuration/dev-server/#devserver-inline-cli-only
[2]: http://gruntjs.com/api/grunt.template
[3]: https://webpack.js.org/configuration/
[4]: https://webpack.js.org/configuration/dev-server/#devserver-port-cli-only
[5]: https://webpack.js.org/configuration/dev-server/#devserver-host-cli-only
[6]: https://webpack.js.org/configuration/dev-server/#devserver-hotonly-cli-only
[7]: https://webpack.js.org/configuration/dev-server/#devserver-public-cli-only
[8]: https://gruntjs.com/configuring-tasks#task-configuration-and-targets
[9]: https://webpack.js.org/guides/get-started/

[grunt-template]: http://gruntjs.com/api/grunt.template
[webpack-config]: https://webpack.js.org/configuration/
[grunt-targets]: https://gruntjs.com/configuring-tasks#task-configuration-and-targets
[webpack-start]: https://webpack.js.org/guides/get-started/
[npm]: https://img.shields.io/npm/v/grunt-webpack.svg
[npm-url]: https://npmjs.com/package/grunt-webpack
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"grunt": "^1.2.1",
"jest": "^26.1.0",
"prettier": "^2.0.5",
"webpack": "^4.17.1"
"webpack": "^5.62.1",
"webpack-dev-server": "^4.4.0"
},
"dependencies": {
"deep-for-each": "^3.0.0",
Expand Down
14 changes: 11 additions & 3 deletions src/options/WebpackDevServerOptionHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class WebpackOptionHelper extends OptionHelper {
}

getWebpackOptions() {
const options = this.getOptions().webpack;
const options = this.getOptions();

if (Array.isArray(options)) {
return options.map((opt) => this.filterGruntOptions(opt));
Expand All @@ -25,9 +25,17 @@ class WebpackOptionHelper extends OptionHelper {
getWebpackDevServerOptions() {
const options = this.getOptions();

delete options.webpack;
if (Array.isArray(options)) {
return options.reduce(
(previous, current) => ({
...previous,
...current.devServer,
}),
{},
);
}

return this.filterGruntOptions(options);
return options.devServer;
}
}

Expand Down
26 changes: 26 additions & 0 deletions src/options/__tests__/WebpackDevServerOptionHelper.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import WebpackDevServerOptionHelper from "../WebpackDevServerOptionHelper";

describe("WebpackDevServerOptionHelper", () => {
test("host is localhost by default", () => {
const options = {};
const helper = new WebpackDevServerOptionHelper();

helper.getRawConfig = () => options;

expect(helper.getWebpackOptions()).toMatchSnapshot();
expect(helper.getWebpackDevServerOptions()).toMatchSnapshot();
});

test("supports array config for webpack", () => {
const options = [
{ devServer: { port: 8080 } },
{ devServer: { port: 9090 } },
];
const helper = new WebpackDevServerOptionHelper();

helper.getOptions = () => options;

expect(helper.getWebpackOptions()).toMatchSnapshot();
expect(helper.getWebpackDevServerOptions()).toMatchSnapshot();
});
});
Loading

0 comments on commit 4d4bbf0

Please sign in to comment.