{"id":13527200,"url":"https://github.com/andywer/webpack-blocks","last_synced_at":"2025-05-12T13:29:54.176Z","repository":{"id":38290604,"uuid":"69284431","full_name":"andywer/webpack-blocks","owner":"andywer","description":"📦 Configure webpack using functional feature blocks.","archived":false,"fork":false,"pushed_at":"2024-10-31T10:07:36.000Z","size":2615,"stargazers_count":2976,"open_issues_count":20,"forks_count":95,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-05-02T07:06:28.978Z","etag":null,"topics":["babel","postcss","typescript","webpack","webpack-blocks"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andywer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-09-26T19:18:30.000Z","updated_at":"2025-04-01T21:30:39.000Z","dependencies_parsed_at":"2023-02-15T11:15:28.641Z","dependency_job_id":"a9fbf02a-ae63-4018-bdbd-3670c7929f7c","html_url":"https://github.com/andywer/webpack-blocks","commit_stats":{"total_commits":541,"total_committers":33,"mean_commits":"16.393939393939394","dds":0.5101663585951941,"last_synced_commit":"ff7f82faaa0f176820415c1dc98407d36f899244"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fwebpack-blocks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fwebpack-blocks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fwebpack-blocks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andywer%2Fwebpack-blocks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andywer","download_url":"https://codeload.github.com/andywer/webpack-blocks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252405092,"owners_count":21742673,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["babel","postcss","typescript","webpack","webpack-blocks"],"created_at":"2024-08-01T06:01:43.132Z","updated_at":"2025-05-12T13:29:54.133Z","avatar_url":"https://github.com/andywer.png","language":"JavaScript","readme":"# webpack-blocks\n\n[![Build Status](https://travis-ci.org/andywer/webpack-blocks.svg?branch=master)](https://travis-ci.org/andywer/webpack-blocks)\n[![Gitter chat](https://badges.gitter.im/webpack-blocks.svg)](https://gitter.im/webpack-blocks)\n\nFunctional building blocks for your webpack config: easier way to configure webpack and to share\nconfiguration between projects.\n\nReady to use blocks to configure popular tools like _Babel_, _PostCSS_, _Sass_, _TypeScript_, etc.,\nas well as best practices like extracting CSS — all with just one line of configuration.\n\nNote: This is the documentation of webpack-blocks v2, compatible with webpack 4. Check out the\n[`v1` branch](https://github.com/andywer/webpack-blocks/tree/v1) if you need to be compatible with\nwebpack 3 or older.\n\n\u003e \"Finally, webpack config done right. (...) Webpack clearly wants to stay low-level. So it makes\n\u003e total sense to outsource configuring it to well designed blocks instead of copy-paste.\"\n\u003e\n\u003e [Dan Abramov](https://github.com/gaearon) via\n\u003e [twitter](https://twitter.com/dan_abramov/status/806249934399881216) (Co-author of Redux, Create\n\u003e React App and React Hot Loader)\n\n## Table of contents\n\n\u003c!-- To update run: npx markdown-toc --maxdepth 2 -i README.md --\u003e\n\n\u003c!-- toc --\u003e\n\n- [Installation](#installation)\n- [Example](#example)\n- [More examples](#more-examples)\n- [Custom blocks](#custom-blocks)\n- [Available webpack blocks](#available-webpack-blocks)\n- [Helpers](#helpers)\n- [Shorthand setters](#shorthand-setters)\n- [Third-party blocks](#third-party-blocks)\n- [Design principles](#design-principles)\n- [FAQ](#faq)\n- [Like what you see?](#like-what-you-see)\n- [Contributors](#contributors)\n- [License](#license)\n\n\u003c!-- tocstop --\u003e\n\n## Installation\n\n```sh\nnpm install --save-dev webpack webpack-blocks\n# or\nyarn add --dev webpack webpack-blocks\n```\n\n## Example\n\nThe following sample shows how to create a webpack config with Babel support, dev server and\nAutoprefixer.\n\n\u003c!-- prettier-ignore-start --\u003e\n```js\nconst webpack = require('webpack')\nconst {\n  createConfig,\n  match,\n\n  // Feature blocks\n  babel,\n  css,\n  devServer,\n  file,\n  postcss,\n  uglify,\n\n  // Shorthand setters\n  addPlugins,\n  setEnv,\n  entryPoint,\n  env,\n  setOutput,\n  sourceMaps\n} = require('webpack-blocks')\nconst autoprefixer = require('autoprefixer')\nconst path = require('path')\n\nmodule.exports = createConfig([\n  entryPoint('./src/main.js'),\n  setOutput('./build/bundle.js'),\n  babel(),\n  match(['*.css', '!*node_modules*'], [\n    css(),\n    postcss({\n      plugins: [\n        autoprefixer({ browsers: ['last 2 versions'] })\n      ]\n    })\n  ]),\n  match(['*.gif', '*.jpg', '*.jpeg', '*.png', '*.webp'], [\n    file()\n  ]),\n  setEnv({\n    NODE_ENV: process.env.NODE_ENV\n  }),\n  env('development', [\n    devServer(),\n    devServer.proxy({\n      '/api': { target: 'http://localhost:3000' }\n    }),\n    sourceMaps()\n  ]),\n  env('production', [\n    uglify(),\n    addPlugins([new webpack.LoaderOptionsPlugin({ minimize: true })])\n  ])\n])\n```\n\u003c!-- prettier-ignore-end --\u003e\n\nSee shorthand setters and helpers [documentation](packages/webpack#exports).\n\nAll blocks, like `babel` or `postcss` are also available as their own [small packages](./packages),\n`webpack-blocks` package wraps these blocks, shorthand setters and helpers as a single dependency\nfor convenience.\n\n## More examples\n\nCSS modules:\n\n```js\nconst { createConfig, match, css } = require('webpack-blocks')\n\n// ...\n\nmodule.exports = createConfig([\n  // ...\n  match(['*.css', '!*node_modules*'], [\n    css.modules()\n  ]\n])\n```\n\nTypeScript:\n\n```js\nconst { createConfig } = require('webpack-blocks')\nconst typescript = require('@webpack-blocks/typescript')\n\n// ...\n\nmodule.exports = createConfig([\n  // ...\n  typescript()\n])\n```\n\n## Custom blocks\n\nNeed a custom block? A simple block looks like this:\n\n```js\nmodule.exports = createConfig([\n  // ...\n  myCssLoader(['./styles'])\n])\n\nfunction myCssLoader() {\n  return (context, { merge }) =\u003e\n    merge({\n      module: {\n        rules: [\n          Object.assign(\n            {\n              test: /\\.css$/,\n              use: ['style-loader', 'my-css-loader']\n            },\n            context.match // carries `test`, `exclude` \u0026 `include` as set by `match()`\n          )\n        ]\n      }\n    })\n}\n```\n\nIf we use `myCssLoader` in `match()` then `context.match` will be populated with whatever we set in\n`match()`. Otherwise there is still the `test: /\\.css$/` fallback, so our block will work without\n`match()` as well.\n\nCheck out the [sample app](./packages/sample-app) to see a webpack config in action or read\n[how to create your own blocks](./docs/BLOCK-CREATION.md).\n\n## Available webpack blocks\n\n- [assets](./packages/assets)\n- [babel](./packages/babel)\n- [dev-server](./packages/dev-server)\n- [elm](https://github.com/webpack-blocks/elm)\n- [eslint](./packages/eslint)\n- [extract-text](./packages/extract-text)\n- [postcss](./packages/postcss)\n- [sass](./packages/sass)\n- [tslint](./packages/tslint)\n- [typescript](./packages/typescript)\n- [uglify](./packages/uglify)\n\n## [Helpers](./packages/webpack#helpers)\n\nHelpers allow you to structure your config and define settings for particular environments (like\n`production` or `development`) or file types.\n\n- group\n- env\n- match\n- when\n\n## [Shorthand setters](./packages/webpack#shorthand-setters)\n\nShorthand setters gives you easier access to common webpack settings, like plugins, entry points and\nsource maps.\n\n- addPlugins\n- customConfig\n- defineConstants\n- entryPoint\n- performance\n- resolve\n- setContext\n- setDevTool\n- setEnv\n- setOutput\n- sourceMaps\n\n## Third-party blocks\n\n- [webpack-blocks-happypack](https://github.com/diegohaz/webpack-blocks-happypack) — HappyPack\n- [webpack-blocks-less](https://github.com/kirill-konshin/webpack-blocks-less) — Less\n- [webpack-blocks-purescript](https://github.com/ecliptic/webpack-blocks-purescript) — PureScript\n- [webpack-blocks-server-source-map](https://github.com/diegohaz/webpack-blocks-server-source-map) —\n  source map for server bundle\n- [webpack-blocks-split-vendor](https://github.com/diegohaz/webpack-blocks-split-vendor) — vendor\n  bundle\n- [webpack-blocks-ts](https://github.com/foxbunny/webpack-blocks-ts) — TypeScript using ts-loader\n  instead of awesome-typescript-loader\n- [webpack-blocks-vue](https://github.com/foxbunny/webpack-blocks-vue) — Vue\n\nMissing something? Write and publish your own webpack blocks!\n\n## Design principles\n\n- Extensibility first\n- Uniformity for easy composition\n- Keep everything configurable\n- But provide sane defaults\n\n## FAQ\n\n\u003cdetails\u003e\n\u003csummary\u003eHow to debug?\u003c/summary\u003e\n\nIn case the webpack configuration does not work as expected you can debug it using\n[q-i](https://www.npmjs.com/package/q-i):\n\n```js\nconst { print } = require('q-i')\n\nmodule.exports = createConfig([\n  // ...\n])\n\nprint(module.exports)\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eHow does env() work?\u003c/summary\u003e\n\n`env('development', [ ... ])` checks the `NODE_ENV` environment variable and only applies its\ncontained webpack blocks if it matches the given string.\n\nSo make sure you set the NODE_ENV accordingly:\n\n```js\n// your package.json\n\"scripts\": {\n  \"build\": \"cross-env NODE_ENV=production webpack\",\n  \"start\": \"cross-env NODE_ENV=development webpack-dev-server\"\n}\n```\n\nIf there is no NODE_ENV set then it will treat NODE_ENV as if it was `development`. Use\n[cross-env](https://github.com/kentcdodds/cross-env) to make it work on all platforms.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eWhat does defineConstants() do?\u003c/summary\u003e\n\n`defineConstants()` is a small convenience wrapper around webpack's\n[DefinePlugin](https://webpack.github.io/docs/list-of-plugins.html#defineplugin). It is composable\nand automatically encodes the values. Use it to replace constants in your code by their values at\nbuild time.\n\nSo having a `defineConstants({ 'process.env.FOO': 'foo' })` and a\n`defineConstants({ 'process.env.BAR': 'bar' })` in your config means the resulting webpack config\nwill contain a single\n`new webpack.DefinePlugin({ 'process.env.FOO': '\"FOO\"', 'process.env.BAR': '\"BAR\"' })`, thus\nreplacing any occurrence of `process.env.FOO` and `process.env.BAR` with the given values.\n\nYou can also use [setEnv](./packages/webpack#setenvconstants-stringobject-function) method to define\n`process.env.*` variables, it’s based on\n[webpack.EnvironmentPlugin](https://webpack.js.org/plugins/environment-plugin/):\n`setEnv({ FOO: 'foo' })`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eWhat does a block look like from the inside?\u003c/summary\u003e\n\nA webpack block is _a function and requires no dependencies at all_ (🎉🎉), thus making it easy to\nwrite your own blocks and share them with your team or the community.\n\nTake the `babel` webpack block for instance:\n\n```js\n/**\n * @param {object} [options]\n * @param {RegExp|Function|string}  [options.exclude]   Directories to exclude.\n * @return {Function}\n */\nfunction babel(options = { cacheDirectory: true }) {\n  return (context, util) =\u003e\n    util.addLoader(\n      Object.assign(\n        {\n          // we use a `MIME type =\u003e RegExp` abstraction here in order to have consistent regexs\n          test: /\\.(js|jsx)$/,\n          exclude: /node_modules/,\n          use: [{ loader: 'babel-loader', options }]\n        },\n        context.match\n      )\n    )\n}\n```\n\nAdd a README and a package.json and you are ready to ship.\n\nFor more details see [How to write a block](./docs/BLOCK-CREATION.md).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eI need some custom webpack config snippet!\u003c/summary\u003e\n\nNo problem. If you don't want to write your own webpack block you can use `customConfig()`:\n\n```js\nconst path = require('path')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst { addPlugins, customConfig } = require('@webpack-blocks/webpack')\n\n// ...\n\nmodule.exports = createConfig([\n  // ...\n  addPlugins([\n    // Add a custom webpack plugin\n    new HtmlWebpackPlugin({\n      inject: true,\n      template: './index.html'\n    })\n  ]),\n  customConfig({\n    // Add some custom webpack config snippet\n    resolve: {\n      extensions: ['.js', '.es6']\n    }\n  })\n])\n```\n\nThe object you pass to `customConfig()` will be merged into the webpack config using\n[webpack-merge](https://github.com/survivejs/webpack-merge) like any other webpack block's partial\nconfig.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eHow to compose blocks?\u003c/summary\u003e\n\nGot some projects with similar, yet not identical webpack configurations? Create a “preset”, a\nfunction that returns a `group` of blocks so you can reuse it in multiple projects:\n\n```js\nconst { createConfig, env, group, babel, devServer } = require('webpack-blocks')\n\nfunction myPreset(proxyConfig) {\n  return group([babel(), env('development', [devServer(), devServer.proxy(proxyConfig)])])\n}\n\nmodule.exports = createConfig([\n  myPreset({\n    '/api': { target: 'http://localhost:3000' }\n  })\n  // add more blocks here\n])\n```\n\nThe key feature is the `group()` method which takes a set of blocks and returns a new block that\ncombines all their functionality.\n\n\u003c/details\u003e\n\n## Like what you see?\n\nSupport webpack-blocks by giving [feedback](https://github.com/andywer/webpack-blocks/issues),\n[contributing to this repository](https://github.com/andywer/webpack-blocks/pulls), publishing new\nwebpack blocks or just by 🌟 starring the project!\n\n## Contributors\n\n[These awesome people](https://github.com/andywer/webpack-blocks/graphs/contributors) have helped\nwebpack-blocks by adding features, fixing bugs and refactoring code. You can become one of them!\n\n## License\n\nMIT\n","funding_links":[],"categories":["JavaScript","Build Tools"],"sub_categories":["React Components"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandywer%2Fwebpack-blocks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandywer%2Fwebpack-blocks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandywer%2Fwebpack-blocks/lists"}