diff --git a/packages/happypack/README.md b/packages/happypack/README.md new file mode 100644 index 00000000..bcaeab31 --- /dev/null +++ b/packages/happypack/README.md @@ -0,0 +1,33 @@ +# Webpack blocks - HappyPack + +This is the `happypack` block providing an easy to use block to support Happypack cache and mutli thread execution. + + +## Usage + +```js +const { createConfig } = require('@webpack-blocks/webpack') +const babel = require('@webpack-blocks/babel') +const sass = require('@webpack-blocks/sass') +const happypack = require('@webpack-blocks/happypack') + +module.exports = createConfig([ + happypack([ + babel(), + sass(), + ], {threads: 4}) +]) +``` + +## Options + +- An array of `webpack-blocks` that are compatible with happypack, [Here the full list](https://github.com/amireh/happypack/wiki/Webpack-Loader-API-Support) +- Happypack options [Here](https://github.com/amireh/happypack/wiki/Webpack-Loader-API-Support) + +## Webpack blocks + +Check out the + +👉 [Main Documentation](https://github.com/andywer/webpack-blocks) + +Released under the terms of the MIT license. diff --git a/packages/happypack/index.js b/packages/happypack/index.js new file mode 100644 index 00000000..41505af8 --- /dev/null +++ b/packages/happypack/index.js @@ -0,0 +1,71 @@ +const { group } = require('@webpack-blocks/core') +const HappyPack = require('happypack'); +const os = require('os'); + +module.exports = happypack + +function happypack(blocks, configs = {}) { + return group(blocks.map((block) => happyfyBlock(block, configs))) +} + +/** + * Returns a new block wrapping `block` that creates a happypack loader config. + */ +function happyfyBlock(block, config) { + const happyBlock = happyfySetter(block, config) + const pre = toArray(block.pre) + const post = toArray(block.post).map(postHook => happyfySetter(postHook, config)) + + return Object.assign(happyBlock, { pre, post }) +} + +/** + * Takes a block or a post hook and returns a wrapping function that creates a happypack loader config. + */ +function happyfySetter(setter, happypackConfig) { + return (context, config) => happyfyConfig(setter(context, config), context, happypackConfig) +} + +/** + * Transforms a non-happypack loader config into a happypack loader config. + */ +function happyfyConfig(configSnippet, _, happypackConfig) { + if (configSnippet.module && configSnippet.module.loaders) { + const plugins = []; + const loaders = configSnippet.module.loaders.map((loader, id) => { + const happypackplugin = new HappyPack(Object.assign({ + id: `loader${id}`, + loaders: loader.loaders, + threads: os.cpus().length, + }, happypackConfig)); + + plugins.push(happypackplugin); + + return { + test: loader.test, + loader: `happypack/loader?id=loader${id}`, + exclude: loader.exclude || [], + } + }); + + return { + module: { + loaders, + }, + plugins, + } + } + return {}; +} + +/** + * Takes an array, a function or something falsy and returns the array, the + * function wrapped in an array or an empty array, respectively. + */ +function toArray(value) { + if (value) { + return Array.isArray(value) ? value : [value] + } else { + return [] + } +} diff --git a/packages/happypack/package.json b/packages/happypack/package.json new file mode 100644 index 00000000..a0fc9c24 --- /dev/null +++ b/packages/happypack/package.json @@ -0,0 +1,24 @@ +{ + "name": "@webpack-blocks/happypack", + "version": "0.0.1", + "description": "Webpack block for happypack", + "main": "lib/index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "engines": { + "node": ">= 4.0" + }, + "keywords": [ + "webpack", + "webpack-blocks", + "happypack" + ], + "repository": "andywer/webpack-blocks", + "bugs": "https://github.com/andywer/webpack-blocks/issues", + "author": "Fabrizio Fenoglio", + "license": "MIT", + "dependencies": { + "happypack": "^3.0.3" + } +}