Functional building blocks for the webpack config. Compose it using feature middlewares like Babel, PostCSS, HMR (Hot Module Replacement), …
Missing anything? Write your own and share them!
"Finally, webpack config done right. (...) Webpack clearly wants to stay low-level. So it makes total sense to outsource configuring it to well designed blocks instead of copy-paste."
Dan Abramov via twitter (Co-author of Redux, Create React App and React Hot Loader)
Version 0.3.x of webpack-blocks comes with a bunch of new features, but also with a major breaking change under the hood.
Every block has been updated, but you have to make sure all webpack-blocks packages you use are version >= 0.3.0 or otherwise all packages are < 0.3.0.
On the upside we don't consider it an early release anymore and the next major release you see might very well be v1.0
👌
npm install --save-dev @webpack-blocks/webpack @webpack-blocks/babel6 ...
Create a webpack 2 config with Babel support, dev server, HMR and PostCSS autoprefixer:
const { createConfig, defineConstants, env, entryPoint, setOutput, sourceMaps } = require('@webpack-blocks/webpack2')
const babel = require('@webpack-blocks/babel6')
const devServer = require('@webpack-blocks/dev-server2')
const postcss = require('@webpack-blocks/postcss')
const autoprefixer = require('autoprefixer')
module.exports = createConfig([
entryPoint('./src/main.js'),
setOutput('./build/bundle.js'),
babel(),
postcss([
autoprefixer({ browsers: ['last 2 versions'] })
]),
defineConstants({
'process.env.NODE_ENV': process.env.NODE_ENV
}),
env('development', [
devServer(),
devServer.proxy({
'/api': { target: 'http://localhost:3000' }
}),
sourceMaps()
])
])
Wanna use CSS modules? No problem!
const cssModules = require('@webpack-blocks/css-modules')
...
module.exports = createConfig([
...
cssModules()
])
Check out the sample app to see a webpack config in action or read how to create your own blocks.
- babel6
- css-modules
- dev-server
- dev-server2 (for Webpack 2)
- extract-text
- extract-text2 (for Webpack 2)
- postcss
- sass
- webpack (Webpack 1 base config)
- webpack2 (Webpack 2 base config)
Missing something? Write and publish your own webpack blocks!
One of the nice gimmicks of using webpack-blocks is that you can switch between webpack versions in an instant!
Just use the webpack 2 versions of the following blocks:
@webpack-blocks/webpack -> @webpack-blocks/webpack2
@webpack-blocks/dev-server -> @webpack-blocks/dev-server2
@webpack-blocks/extract-text -> @webpack-blocks/extract-text2
- Extensibility first
- Uniformity for easy composition
- Keep everything configurable
- But provide sane defaults
You have got some projects with a similar, yet not identical webpack configuration? Seems like you are looking for something preset-ish!
Fortunately, this is also very simple:
const { env, group } = require('@webpack-blocks/webpack')
const babel = require('@webpack-blocks/babel6')
const devServer = require('@webpack-blocks/dev-server')
function myPreset (proxyConfig) {
return group([
babel(),
env('development', [
devServer(),
devServer.proxy(proxyConfig)
])
])
}
The key feature is the group()
method which takes a set of blocks and returns a new block that combines all their functionality.
Then use your preset like this:
const { createConfig } = require('@webpack-blocks/webpack')
module.exports = createConfig([
myPreset({
'/api': { target: 'http://localhost:3000' }
}),
... // add more blocks here
])
How does env() work?
You might wonder how env('development', [ ... ])
works? It just checks the NODE_ENV environment variable and only applies its contained webpack blocks if it matches.
So make sure you set the NODE_ENV accordingly:
// your package.json
"scripts": {
"build": "NODE_ENV=production webpack --config webpack.config.js",
"start": "NODE_ENV=development webpack-dev-server --config webpack.config.js"
}
If there is no NODE_ENV set then it will just treat NODE_ENV as if it was development
.
What does a block look like from the inside?
A webpack block is just a function and requires no dependencies at all (🎉🎉), thus making it easy to write your own blocks and share them with the community.
Take the babel6
webpack block for instance:
/**
* @param {object} [options]
* @param {RegExp|Function|string} [options.exclude] Directories to exclude.
* @return {Function}
*/
function babel (options) {
const { exclude = /\/node_modules\// } = options || {}
return (context) => ({
module: {
loaders: [
{
// we use a `MIME type => RegExp` abstraction here in order to have consistent regexs
test: context.fileType('application/javascript'),
exclude: Array.isArray(exclude) ? exclude : [ exclude ],
loaders: [ 'babel-loader?cacheDirectory' ]
}
]
}
})
}
Add a README and a package.json and you are ready to ship.
For more details see How to write a block.
I need some custom webpack config snippet!
No problem. If you don't want to write your own webpack block you can just use customConfig()
:
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { addPlugins, customConfig } = require('@webpack-blocks/webpack')
...
module.exports = createConfig([
...
addPlugins([
// Add a custom we
7B76
bpack plugin
new HtmlWebpackPlugin({
inject: true,
template: './index.html'
})
]),
customConfig({
// Add some custom webpack config snippet
resolve: {
extensions: [ '.js', '.es6' ]
}
})
])
The object you pass to customConfig()
will be merged into the webpack config using
webpack-merge like any other webpack
block's partial config.
Support webpack-blocks by giving feedback, publishing new webpack blocks or just by 🌟 starring the project!