grunt-webpack
Advanced tools
Comparing version 2.0.1 to 3.0.0-beta.1
{ | ||
"name": "grunt-webpack", | ||
"description": "Use webpack with grunt.", | ||
"version": "2.0.1", | ||
"version": "3.0.0-beta.1", | ||
"homepage": "https://github.com/webpack-contrib/grunt-webpack", | ||
@@ -24,3 +24,3 @@ "author": { | ||
"peerDependencies": { | ||
"webpack": "^2.1.0-beta || ^2.2.0-rc || ^2.0.0" | ||
"webpack": "^2.1.0-beta || ^2.2.0-rc || 2" | ||
}, | ||
@@ -32,15 +32,13 @@ "license": "MIT", | ||
"scripts": { | ||
"coverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json", | ||
"lint": "eslint src tasks", | ||
"preversion": "npm test", | ||
"test": "npm run lint && npm run test-only", | ||
"test-ci": "nyc npm run test-only", | ||
"test-coverage": "nyc --reporter=json --reporter=text npm run test-only", | ||
"test-only": "ava" | ||
}, | ||
"devDependencies": { | ||
"ava": "^0.17.0", | ||
"ava": "^0.18.2", | ||
"babel-core": "^6.17.0", | ||
"babel-loader": "^6.2.9", | ||
"babel-preset-latest": "^6.16.0", | ||
"codecov": "^1.0.1", | ||
"eslint": "^3.6.1", | ||
@@ -54,2 +52,3 @@ "fs-extra": "^2.0.0", | ||
"dependencies": { | ||
"deep-for-each": "^1.0.5", | ||
"lodash": "^4.7.0" | ||
@@ -66,2 +65,3 @@ }, | ||
"nyc": { | ||
"all": true, | ||
"include": [ | ||
@@ -68,0 +68,0 @@ "src/", |
250
README.md
@@ -1,86 +0,230 @@ | ||
# grunt-webpack [![Build Status](https://travis-ci.org/webpack-contrib/grunt-webpack.svg?branch=master)](https://travis-ci.org/webpack-contrib/grunt-webpack) [![codecov](https://codecov.io/gh/webpack-contrib/grunt-webpack/branch/master/graph/badge.svg)](https://codecov.io/gh/webpack-contrib/grunt-webpack) | ||
[![npm][npm]][npm-url] | ||
[![deps][deps]][deps-url] | ||
[![test][test]][test-url] | ||
[![coverage][cover]][cover-url] | ||
[![chat][chat]][chat-url] | ||
**This is the readme for version 2.0 which is currently available as beta version. For the 1.0 readme visit [here](https://github.com/webpack-contrib/grunt-webpack/tree/1.0).** | ||
<div align="center"> | ||
<!-- replace with accurate logo e.g from https://worldvectorlogo.com/ --> | ||
<img width="200" height="200" | ||
src="https://cdn.worldvectorlogo.com/logos/grunt.svg"> | ||
<a href="https://github.com/webpack/webpack"> | ||
<img width="200" height="200" vspace="" hspace="25" | ||
src="https://cdn.rawgit.com/webpack/media/e7485eb2/logo/icon.svg"> | ||
</a> | ||
<h1>Grunt Webpack</h1> | ||
<p>Use Webpack with Grunt.<p> | ||
</div> | ||
Use [webpack](https://github.com/webpack/webpack) with grunt. | ||
**This is the readme for version 2.0 which is currently available as beta version. For the 1.0 readme visit [here](https://github.com/webpack-contrib/grunt-webpack/tree/1.0).** | ||
## Getting Started | ||
<h2 align="center">Install</h2> | ||
Install this grunt plugin next to your project's [Gruntfile.js](http://gruntjs.com/getting-started) with: | ||
Install this grunt plugin next to your project's [Gruntfile.js](http://gruntjs.com/getting-started). You also need to install webpack yourself, this grunt plugin does not install webpack itself. | ||
```bash | ||
npm install grunt-webpack --save-dev | ||
yarn add webpack grunt-webpack --dev | ||
``` | ||
You can still use npm | ||
```bash | ||
npm i webpack grunt-webpack --save-dev | ||
``` | ||
If you also want to use the webpack-dev-server task you also need to install `webpack-dev-server` | ||
```bash | ||
yarn add webpack-dev-server --dev | ||
``` | ||
Then add this line to your project's `Gruntfile.js` gruntfile: | ||
```javascript | ||
grunt.loadNpmTasks('grunt-webpack'); | ||
module.exports = function(grunt) { | ||
// Project configuration. | ||
grunt.initConfig({ ... }); | ||
grunt.loadNpmTasks('grunt-webpack'); | ||
}; | ||
``` | ||
## Tasks | ||
<h2 align="center">Configuration</h2> | ||
There are two tasks available | ||
- `webpack`. | ||
- `webpack-dev-server`: see [webpack-dev-server doc](http://webpack.github.io/docs/webpack-dev-server.html#api) for available options. | ||
`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. | ||
## Configuration Example | ||
### 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) | ||
When set to true the grunt process will be kept alive after webpack task is finished. This is especially usefull for `watch` and `webpack-dev-server` as these usually need to run as long as not manually killed. | ||
### Webpack Task | ||
#### failOnError | ||
Type: `bool` | ||
Default: `true` (`false` if watch mode is used) | ||
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. | ||
#### storeStatsTo | ||
Type: `string` | ||
Default: `null` | ||
When set the stats from webpack will be written to a variable with the name provided in this option. The variable can later be used inside of other grunt tasks with template tags `<%= %>`. | ||
```js | ||
... | ||
storeStatsTo: "webpackStats" | ||
... | ||
<%= webpackStats.hash %> | ||
... | ||
``` | ||
> For more information about grunt template tags have a look at the [grunt docs][2]. | ||
### 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. | ||
<h2 align="center">Examples</h2> | ||
### Webpack | ||
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 | ||
webpack: { | ||
someName: { | ||
// webpack options | ||
entry: "./client/lib/index.js", | ||
output: { | ||
path: "asserts/", | ||
filename: "[hash].js", | ||
}, | ||
const webpackConfig = require('./webpack.config'); | ||
stats: { | ||
// Configure the console output | ||
colors: false, | ||
modules: true, | ||
reasons: true | ||
}, | ||
// stats: false disables the stats output | ||
module.exports = function(grunt) { | ||
grunt.initConfig({ | ||
webpack: { | ||
options: { | ||
stats: !process.env.NODE_ENV || process.env.NODE_ENV === 'development' | ||
}, | ||
prod: webpackConfig, | ||
dev: Object.assign({ watch: true }, webpackConfig) | ||
} | ||
}); | ||
storeStatsTo: "xyz", // writes the status to a variable named xyz | ||
// you may use it later in grunt i.e. <%= xyz.hash %> | ||
grunt.loadNpmTasks('grunt-webpack'); | ||
}; | ||
``` | ||
progress: false, // Don't show progress | ||
// Defaults to true | ||
> 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][2] for more information about targets. | ||
failOnError: false, // don't report error to grunt if webpack find errors | ||
// Use this if webpack errors are tolerable and grunt should continue | ||
On the command line you can then do the following. | ||
watch: true, // use webpacks watcher | ||
// You need to keep the grunt process alive | ||
```bash | ||
# Run webpack with the `prod` target | ||
> NODE_ENV='production' grunt webpack:prod | ||
watchOptions: { | ||
aggregateTimeout: 500, | ||
poll: true | ||
}, | ||
// Use this when you need to fallback to poll based watching (webpack 1.9.1+ only) | ||
# Run webpack with the `dev` target | ||
> grunt webpack:dev | ||
keepalive: true, // don't finish the grunt task | ||
// defaults to true for watch and dev-server otherwise false | ||
# Run webpack for all targets | ||
> grunt webpack | ||
``` | ||
inline: true, // embed the webpack-dev-server runtime into the bundle | ||
// Defaults to false | ||
> For more examples and information have a look at the [webpack documentation][9] which mostly also applies here besides the noted differences above. | ||
hot: true, // adds the HotModuleReplacementPlugin and switch the server to hot mode | ||
// Use this in combination with the inline option | ||
<h2 align="center">Troubleshooting</h2> | ||
}, | ||
anotherName: {...} | ||
} | ||
### Circular reference detected (.plugins) | ||
If you encounter this message it means that one of the plugins which are present in your config have circular references. | ||
This is totally fine for webpack, but sadly grunt cannot handle these. | ||
To workaround this problem use lazy config loading, by wrapping your config inside a function. | ||
```js | ||
module.exports = function(grunt) { | ||
grunt.initConfig({ | ||
webpack: { | ||
myconfig: function() { | ||
return { | ||
plugins: [...] | ||
}; | ||
} | ||
} | ||
}); | ||
grunt.loadNpmTasks('grunt-webpack'); | ||
}; | ||
``` | ||
`grunt-webpack` uses the [webpack options](http://webpack.github.io/docs/configuration.html). | ||
<h2 align="center">Maintainers</h2> | ||
<table> | ||
<tbody> | ||
<tr> | ||
<td align="center"> | ||
<img width="150" height="150" | ||
src="https://avatars1.githubusercontent.com/u/231804?v=3&s=150"> | ||
</br> | ||
<a href="https://github.com/danez">Daniel Tschinder</a> | ||
</td> | ||
<td align="center"> | ||
<img width="150" height="150" | ||
src="https://avatars3.githubusercontent.com/u/166921?v=3&s=150"> | ||
</br> | ||
<a href="https://github.com/bebraw">Juho Vepsäläinen</a> | ||
</td> | ||
<td align="center"> | ||
<img width="150" height="150" | ||
src="https://avatars2.githubusercontent.com/u/8420490?v=3&s=150"> | ||
</br> | ||
<a href="https://github.com/d3viant0ne">Joshua Wiens</a> | ||
</td> | ||
<td align="center"> | ||
<img width="150" height="150" | ||
src="https://avatars3.githubusercontent.com/u/533616?v=3&s=150"> | ||
</br> | ||
<a href="https://github.com/SpaceK33z">Kees Kluskens</a> | ||
</td> | ||
<td align="center"> | ||
<img width="150" height="150" | ||
src="https://avatars3.githubusercontent.com/u/3408176?v=3&s=150"> | ||
</br> | ||
<a href="https://github.com/TheLarkInn">Sean Larkin</a> | ||
</td> | ||
</tr> | ||
<tbody> | ||
</table> | ||
## License | ||
[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/ | ||
Copyright (c) JS Foundation | ||
[npm]: https://img.shields.io/npm/v/grunt-webpack.svg | ||
[npm-url]: https://npmjs.com/package/grunt-webpack | ||
MIT (http://opensource.org/licenses/mit-license.php) | ||
[deps]: https://david-dm.org/webpack-contrib/grunt-webpack.svg | ||
[deps-url]: https://david-dm.org/webpack-contrib/grunt-webpack | ||
[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg | ||
[chat-url]: https://gitter.im/webpack/webpack | ||
[test]: https://travis-ci.org/webpack-contrib/grunt-webpack.svg?branch=master | ||
[test-url]: https://travis-ci.org/webpack-contrib/grunt-webpack | ||
[cover]: https://codecov.io/gh/webpack-contrib/grunt-webpack/branch/master/graph/badge.svg | ||
[cover-url]: https://codecov.io/gh/webpack-contrib/grunt-webpack |
@@ -6,3 +6,6 @@ 'use strict'; | ||
const gruntOptions = { | ||
failOnError: true, | ||
failOnError: (options) => { | ||
// if watch enabled also default to failOnError false | ||
return Array.isArray(options) ? options.every(option => !option.watch) : !options.watch; | ||
}, | ||
progress: process.stdout.isTTY, | ||
@@ -12,5 +15,4 @@ storeStatsTo: null, | ||
// if watch enabled also default to keepalive true | ||
return Array.isArray(options) ? options.some(option => option.watch) : Boolean(options.watch); | ||
return Array.isArray(options) ? options.some(option => option.watch) : !!options.watch; | ||
}, | ||
inline: false, | ||
}; | ||
@@ -20,11 +22,10 @@ | ||
stats: { | ||
cached: false, | ||
cachedAssets: false, | ||
colors: true, | ||
hash: false, | ||
timings: false, | ||
assets: true, | ||
chunks: false, | ||
chunkModules: false, | ||
modules: false, | ||
children: true, | ||
}, | ||
cache: (options) => { | ||
// if watch enabled also default to cache true | ||
return Array.isArray(options) ? options.some(option => option.watch) : !!options.watch; | ||
} | ||
}; | ||
@@ -35,13 +36,9 @@ | ||
host: 'localhost', | ||
hot: false, | ||
inline: true, | ||
keepalive: true, | ||
publicPath: '/', | ||
stats: { | ||
colors: true, | ||
hash: false, | ||
timings: false, | ||
assets: true, | ||
chunks: false, | ||
chunkModules: false, | ||
modules: false, | ||
children: true | ||
cached: false, | ||
cachedAssets: false | ||
}, | ||
@@ -48,0 +45,0 @@ }; |
'use strict'; | ||
const deepForEach = require('deep-for-each'); | ||
const defaults = require('./default'); | ||
@@ -50,28 +51,16 @@ | ||
getWithPlugins(ns) { | ||
const obj = this.grunt.config(ns) || {}; | ||
let obj = this.grunt.config.getRaw(ns) || {}; | ||
if (Array.isArray(obj)) { | ||
obj.forEach((options, index) => { | ||
this.fixPlugins(options, ns.concat([`${index}`, 'plugins'])); | ||
}); | ||
} else { | ||
if (obj.webpack) { | ||
// handle webpack-dev-server options | ||
this.fixPlugins(obj.webpack, ns.concat(['webpack', 'plugins'])); | ||
} else { | ||
this.fixPlugins(obj, ns.concat(['plugins'])); | ||
} | ||
if (typeof obj === 'function') { | ||
obj = obj(); | ||
} | ||
return obj; | ||
} | ||
deepForEach(obj, function (value, key, parent) { | ||
if (typeof value === 'string') { | ||
parent[key] = this.grunt.config.process(value); | ||
} else if (Array.isArray(value) && key === 'plugins') { | ||
parent[key] = value.map(plugin => this.fixPlugin(plugin)); | ||
} | ||
}.bind(this)); | ||
fixPlugins(obj, ns) { | ||
if (obj.plugins) { | ||
// getRaw must be used or grunt.config will clobber the types (i.e. | ||
// the array won't a BannerPlugin, it will contain an Object) | ||
const plugins = this.grunt.config.getRaw(ns); | ||
obj.plugins = plugins.map(plugin => this.fixPlugin(plugin)); | ||
} | ||
return obj; | ||
@@ -88,3 +77,5 @@ } | ||
if (typeof plugin[key] === 'string') { | ||
instance[key] = this.grunt.template.process(plugin[key]); | ||
instance[key] = this.grunt.config.process(plugin[key]); | ||
} else { | ||
instance[key] = plugin[key]; | ||
} | ||
@@ -91,0 +82,0 @@ }); |
@@ -24,10 +24,2 @@ 'use strict'; | ||
if (Array.isArray(options)) { | ||
return options.map((opt) => { | ||
delete options.webpack; | ||
return this.filterGruntOptions(opt); | ||
}); | ||
} | ||
delete options.webpack; | ||
@@ -34,0 +26,0 @@ |
@@ -10,18 +10,4 @@ 'use strict'; | ||
addPlugin(target, compiler) { | ||
let chars = 0; | ||
compiler.apply(new ProgressPlugin((percentage, msg) => { | ||
if (percentage < 1) { | ||
percentage = Math.floor(percentage * 100); | ||
msg = percentage + '% ' + msg; | ||
if (percentage < 100) msg = ' ' + msg; | ||
if (percentage < 10) msg = ' ' + msg; | ||
} | ||
for (; chars > msg.length; chars--) | ||
this.grunt.log.write('\b \b'); | ||
chars = msg.length; | ||
for (let i = 0; i < chars; i++) | ||
this.grunt.log.write('\b'); | ||
this.grunt.log.write(msg); | ||
})); | ||
addPlugin(compiler, options) { | ||
compiler.apply(new ProgressPlugin({ profile: options.profile })); | ||
} | ||
@@ -28,0 +14,0 @@ } |
@@ -5,4 +5,23 @@ 'use strict'; | ||
const ProgressPluginFactory = require('../src/plugins/ProgressPluginFactory'); | ||
const HotModuleReplacementPluginFactory = require('../src/plugins/HotModuleReplacementPluginFactory'); | ||
function colorInfo(useColor, msg) { | ||
// Make text blue and bold, so it *pops* | ||
if (useColor) return `\u001b[1m\u001b[34m${msg}\u001b[39m\u001b[22m`; | ||
return msg; | ||
} | ||
function reportReadiness(uri, options, grunt) { | ||
const useColor = !options.stats || options.stats.colors; | ||
grunt.log.writeln((options.progress ? '\n' : '') + `Project is running at ${colorInfo(useColor, uri)}`); | ||
grunt.log.writeln(`webpack output is served from ${colorInfo(useColor, options.publicPath)}`); | ||
const contentBase = Array.isArray(options.contentBase) ? options.contentBase.join(', ') : options.contentBase; | ||
if (contentBase) | ||
grunt.log.writeln(`Content not from webpack is served from ${colorInfo(useColor, contentBase)}`); | ||
if (options.historyApiFallback) | ||
grunt.log.writeln(`404s will fallback to ${colorInfo(useColor, options.historyApiFallback.index || '/index.html')}`); | ||
} | ||
module.exports = (grunt) => { | ||
@@ -18,5 +37,6 @@ let WebpackDevServer; | ||
To fix this problem install webpack-dev-server by doing either | ||
npm install --save webpack-dev-server | ||
or | ||
yarn add webpack-dev-server`); | ||
yarn add webpack-dev-server --dev | ||
or | ||
npm install --save-dev webpack-dev-server | ||
`); | ||
}); | ||
@@ -26,4 +46,8 @@ return; | ||
if (typeof WebpackDevServer.addDevServerEntrypoints !== 'function') { | ||
grunt.fail.fatal('webpack-dev-server is outdated. Please ensure you have at least version 2.4.0 installed.'); | ||
} | ||
const createDomain = require('webpack-dev-server/lib/util/createDomain'); | ||
const processPluginFactory = new ProgressPluginFactory(grunt); | ||
const hotModuleReplacementPluginFactory = new HotModuleReplacementPluginFactory(grunt); | ||
@@ -33,32 +57,10 @@ grunt.registerMultiTask('webpack-dev-server', 'Start a webpack-dev-server.', function webpackDevServerTask() { | ||
const optionHelper = new OptionHelper(grunt, this); | ||
const opts = { | ||
host: optionHelper.get('host'), | ||
hot: optionHelper.get('hot'), | ||
https: optionHelper.get('https'), | ||
inline: optionHelper.get('inline'), | ||
keepalive: optionHelper.get('keepalive'), | ||
port: optionHelper.get('port'), | ||
progress: optionHelper.get('progress') | ||
}; | ||
const opts = optionHelper.getOptions(); | ||
const webpackOptions = optionHelper.getWebpackOptions(); | ||
if (opts.inline) { | ||
const protocol = opts.https ? 'https' : 'http'; | ||
const devClient = [ | ||
`webpack-dev-server/client?${protocol}://${opts.host}:${opts.port}` | ||
]; | ||
if (opts.hot) devClient.push('webpack/hot/dev-server'); | ||
WebpackDevServer.addDevServerEntrypoints(webpackOptions, opts); | ||
// TODO can ww extract that and make it nice | ||
[].concat(webpackOptions).forEach((webpackOptions) => { | ||
if (typeof webpackOptions.entry === 'object' && !Array.isArray(webpackOptions.entry)) { | ||
Object.keys(webpackOptions.entry).forEach((key) => { | ||
webpackOptions.entry[key] = devClient.concat(webpackOptions.entry[key]); | ||
}); | ||
} else { | ||
webpackOptions.entry = devClient.concat(webpackOptions.entry); | ||
} | ||
}); | ||
if (opts.inline && (opts.hotOnly || opts.hot)) { | ||
webpackOptions.plugins = webpackOptions.plugins || []; | ||
webpackOptions.plugins.push(new webpack.HotModuleReplacementPlugin()); | ||
} | ||
@@ -68,9 +70,7 @@ | ||
if (opts.progress) processPluginFactory.addPlugin(this.target, compiler); | ||
if (opts.progress) processPluginFactory.addPlugin(compiler, webpackOptions); | ||
// TODO does this work? or do we add the module in the initial config? | ||
if (opts.inline && opts.hot) hotModuleReplacementPluginFactory.addPlugin(this.target, compiler); | ||
(new WebpackDevServer(compiler, optionHelper.getWebpackDevServerOptions())).listen(opts.port, opts.host, () => { | ||
grunt.log.writeln(`\rwebpack-dev-server on port ${opts.port} `); | ||
const uri = createDomain(opts) + (opts.inline !== false || opts.lazy === true ? '/' : '/webpack-dev-server/'); | ||
reportReadiness(uri, opts, grunt); | ||
if (!opts.keepalive) done(); | ||
@@ -77,0 +77,0 @@ }); |
'use strict'; | ||
const webpack = require('webpack'); | ||
const pkg = require('../package.json'); | ||
const OptionHelper = require('../src/options/WebpackOptionHelper'); | ||
@@ -31,3 +32,3 @@ const CachePluginFactory = require('../src/plugins/CachePluginFactory'); | ||
if (opts.cache) cachePluginFactory.addPlugin(this.target, compiler); | ||
if (opts.progress) processPluginFactory.addPlugin(this.target, compiler); | ||
if (opts.progress) processPluginFactory.addPlugin(compiler, webpackOptions); | ||
@@ -39,3 +40,8 @@ const handler = (err, stats) => { | ||
if (opts.stats && !stats.hasErrors()) { | ||
grunt.log.writeln(stats.toString(opts.stats)); | ||
grunt.log.writeln( | ||
stats | ||
.toString(opts.stats) | ||
// add plugin version with and without colors | ||
.replace(/(\n(.*)Version: webpack (.*)\d+\.\d+\.\d+(.*))\n/, `$1$2 / grunt-webpack $3${pkg.version}$4\n`) | ||
); | ||
} | ||
@@ -42,0 +48,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21883
10
231
3
11
327
1
+ Addeddeep-for-each@^1.0.5
+ Addeddeep-for-each@1.0.6(transitive)