Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack Helpers v1 Beta: Webpack 5, addFilter() #205

Open
wants to merge 83 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
dcf2eb6
Upgrade dependencies for Webpack 5 / Node 14-16
kadamwhite Apr 28, 2022
4cb27d0
Pin Chalk to v4 for node compatibility (see note)
kadamwhite Apr 28, 2022
f6cc586
Update choose-port to latest react-dev-utils version
kadamwhite Apr 28, 2022
c697a40
Use Asset Modules over url-loader and file-loader
kadamwhite Apr 28, 2022
b3c8d52
Switch to Webpack 5-compatible CSS optimizer plugin
kadamwhite Apr 28, 2022
a7fbc9b
Add source-map-loader, borrowed from latest CRA
kadamwhite Apr 28, 2022
287723c
JSX pragma is now baked into WordPress babel preset
kadamwhite Apr 28, 2022
069375f
Update to latest TerserPlugin config from CRA
kadamwhite Apr 28, 2022
d866674
Update webpack devserver config for devServer v4
kadamwhite Apr 28, 2022
6898a3b
Update unit tests for asset module changes
kadamwhite Apr 28, 2022
880aaef
Remove duplicative dependencies from package.json
kadamwhite Apr 28, 2022
d75ca23
Bump version to 1.0.0-beta.0
kadamwhite Apr 28, 2022
d3256e6
Replace filterLoaders system with a more generic addFilter hook system
kadamwhite Apr 28, 2022
4a7a5a2
Remove support for Node 10
kadamwhite Apr 29, 2022
f1a4646
Set publicPath to "" to avoid issues with "auto"
kadamwhite Apr 29, 2022
7755c07
Tag v1.0.0-beta.1
kadamwhite Apr 29, 2022
e702595
Update src/loaders.js
kadamwhite Apr 29, 2022
5e4d73b
Hash filenames by default
kadamwhite Apr 29, 2022
a08e8a0
Limit CSS filename hash to 8 characters
kadamwhite Apr 29, 2022
f70f124
Fix test to expect more flexible html regex
kadamwhite Apr 29, 2022
b876ecb
Consolidate filters used for presets, props @tfrommen
kadamwhite Apr 29, 2022
1bd56aa
Tag v1.0.0-beta.2
kadamwhite Apr 29, 2022
6432ae9
Use "development-asset-manifest.json" in dev mode for clarity
kadamwhite Apr 29, 2022
96cbc41
Tag v1.0.0-beta.3
kadamwhite Apr 29, 2022
cc71e96
Document manifest name change
kadamwhite Apr 29, 2022
02d7b13
Fix tests after beta.3 change and improve manifest documentation
kadamwhite Apr 29, 2022
1173405
Ignore DS_Store files
kadamwhite May 17, 2022
c30ef09
Allow loader to be skipped when rendering preset by filtering it to null
kadamwhite May 17, 2022
f5d7c10
Tag v1.0.0-beta.4
kadamwhite May 17, 2022
1645bbc
Detect HTTPS when using the devServer.server flag (devServer.https is…
kadamwhite May 17, 2022
9dbc218
Simplify function body of removeNullLoaders helper
kadamwhite May 17, 2022
0e48396
Update tests to use devServer.server:"https" instead of devServer.htt…
kadamwhite May 17, 2022
1d59d74
Tag v1.0.0-beta.5
kadamwhite May 17, 2022
ef6449f
Expose removeFilter in addition to addFilter
kadamwhite May 18, 2022
df1eef8
Tag v1.0.0-beta.6
kadamwhite May 18, 2022
05a8fc8
Remove eslint-loader and add eslint-webpack-plugin
kadamwhite May 21, 2022
a5d0051
Add test to test-build to validate linting behavior
kadamwhite May 21, 2022
e8e3054
Swap out fix-style-only-entries plugin for "webpack-remove-empty-scri…
kadamwhite May 21, 2022
bf9e4a4
Do not include lint validation in prod build test because it causes C…
kadamwhite May 21, 2022
8410f9c
Remove leftover loaders.eslint() reference
kadamwhite May 22, 2022
62f38f8
Preserve spacing in JSON
kadamwhite May 22, 2022
1420643
Switch back to 16-character hashes (Asset_Loader expects this)
kadamwhite May 22, 2022
7d10a73
Adjust build stats defaults and apply to dev builds as well
kadamwhite May 22, 2022
ad40f3a
Filter out null plugin instances
kadamwhite May 22, 2022
a88e280
Add SimpleBuildReportPlugin and expose via plugins.formatConsoleOutput
kadamwhite May 22, 2022
ca2005e
Include a bundleAnalyzer plugin by default when --analyze is passed t…
kadamwhite May 23, 2022
04f2615
Include simpleBuildReport plugin in production presets
kadamwhite May 23, 2022
82fb64c
Tag v1.0.0-beta.7
kadamwhite May 23, 2022
8eaa3c9
Correct language in changelog around loader filtering
kadamwhite May 23, 2022
cdd57b2
Do not deep-merge terserOptions, so that terser can be predictably co…
kadamwhite May 23, 2022
bcd10ad
Permit filtering Terser defaults
kadamwhite May 23, 2022
1055650
Change filter strings from "loader/...", "plugin/..." etc to "loaders…
kadamwhite May 23, 2022
bc37992
Document the addFilter and removeFilter modules
kadamwhite May 23, 2022
0743793
Finish converting loader names from "loader/" to "loaders/"
kadamwhite May 23, 2022
cde3aee
Tag v1.0.0-beta.8
kadamwhite May 23, 2022
1591e84
Fix issue where simple build report plugin was listed as dev dependency
kadamwhite May 23, 2022
ee6d541
Tag v1.0.0-beta.9
kadamwhite May 23, 2022
e632c89
Add note about returning null from loader
kadamwhite May 24, 2022
bfbf059
Fix bug where isObj in deep-merge would return true for "null"
kadamwhite May 24, 2022
015ad69
Include modern image formats in image asset test
kadamwhite May 24, 2022
4ad3c3e
Upgrade bundled SimpleBuildReportPlugin
kadamwhite May 24, 2022
c319d17
Tag v1.0.0-beta.10
kadamwhite May 24, 2022
e95a890
Provide preset config as filter argument when appropriate (#207)
kadamwhite Jun 15, 2022
dc67783
Author initial upgrade guide
kadamwhite Jun 15, 2022
0a892f5
Tag v1.0.0-beta.11
kadamwhite Jun 15, 2022
b12898a
Do not pass loader defaults to filters by reference to prevent mutation
kadamwhite Jun 16, 2022
fa464e3
Tag v1.0.0-beta.12
kadamwhite Jun 16, 2022
a20b4d8
Expand multi-config DevServer documentation
kadamwhite Jun 17, 2022
046b247
Standardize JSDoc on @returns instead of @return
kadamwhite Jun 22, 2022
b42bf86
Inject development-mode asset manifest even without publicPath
kadamwhite Jul 1, 2022
3201d61
Switch from [contenthash] back to [fullhash] (prev [hash]) in Dev config
kadamwhite Jul 1, 2022
870f4f0
Set runtimeChunk: "single" to work around HMR issue with multiple ent…
kadamwhite Jul 1, 2022
0e69dcd
Tag v1.0.0-beta.13
kadamwhite Jul 1, 2022
a2637c5
Automatically set devServer "host" property when we can
kadamwhite Jul 1, 2022
583b5ab
Tag v1.0.0-beta.14
kadamwhite Jul 1, 2022
20fff25
Remove check for whether devServer is running, devServer is not relev…
kadamwhite Jul 1, 2022
bfa8c6a
Revert switch to runtimeChunk: single, which requires unintuitive oth…
kadamwhite Jul 1, 2022
122790e
Tag v1.0.0-beta.15
kadamwhite Jul 1, 2022
c7e9e6a
Only show DevServer overlay for errors, not warnings
kadamwhite Jul 1, 2022
301a0f1
Store and re-use inferred publicPaths in subsequent builds to the sam…
kadamwhite Jul 1, 2022
77d09e9
Tag v1.0.0-beta.16
kadamwhite Jul 1, 2022
637e695
Pin [email protected]
kadamwhite May 17, 2023
4195d37
Tag v1.0.0-beta.17
kadamwhite May 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ insert_final_newline = true
indent_style = tab
trim_trailing_whitespace = true

# YAML files require spaces
[*.{yaml,yml}]
# YAML files require spaces. JSON doesn't, but our file uses them.
[*.{yaml,yml,json}]
indent_style = space
indent_size = 2
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ docs/
src/vendor

# The test folder uses ES modules
test/src
test/build
9 changes: 6 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ module.exports = {
'new-parens': 'error',
'newline-after-var': 'off',
'newline-before-return': 'off',
'newline-per-chained-call': 'error',
'newline-per-chained-call': 'off',
'no-alert': 'error',
'no-array-constructor': 'error',
'no-async-promise-executor': 'error',
Expand All @@ -127,7 +127,7 @@ module.exports = {
'no-extra-label': 'error',
'no-extra-parens': 'off',
'no-floating-decimal': 'error',
'no-implicit-coercion': 'error',
'no-implicit-coercion': 'off',
'no-implicit-globals': 'error',
'no-implied-eval': 'error',
'no-inline-comments': 'error',
Expand Down Expand Up @@ -251,7 +251,10 @@ module.exports = {
'error',
'last'
],
'sort-imports': 'error',
'sort-imports': [
'error',
{ memberSyntaxSortOrder: [ 'all', 'multiple', 'single', 'none' ] },
],
'sort-keys': 'off',
'sort-vars': 'error',
'space-before-blocks': 'error',
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules
*.log
package-lock.json
test/build

.DS_Store
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
language: node_js
script: "npm run lint && npm run test && npm run test-build"
node_js:
- node
- lts/*
- 16
- 14
- 12
- 10
branches:
only:
- main
- beta
- v1
9 changes: 2 additions & 7 deletions babel-preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ module.exports = ( api ) => {
api.cache.forever();

return {
presets: [ '@wordpress/default' ],
plugins: [
'@babel/plugin-proposal-class-properties',
[ 'transform-react-jsx', {
pragma: 'wp.element.createElement',
} ],
],
presets: [ '@wordpress/babel-preset-default' ],
plugins: [ '@babel/plugin-proposal-class-properties' ],
};
};
21 changes: 19 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,25 @@ nav_order: 10

# Changelog

## Next

## v1.0

- **Breaking**: End support for Node v10. Node v12.13 or later is now required.
- **Breaking**: Switch to Webpack 5 and Webpack DevServer 4
- **Breaking**: Include a contenthash string in default bundle file names. Set `filename: '[name].js'` in your output configuration to restore the old behavior.
- **Breaking**: Default DevServer manifest name is now `development-asset-manifest.json`, not `asset-manifest.json`.
- **Breaking**: Replace `filterLoaders` system with [individual hooks accesible via the new `addFilter` and `removeFilter` helpers](https://humanmade.github.io/webpack-helpers/modules/presets.html#customizing-presets).
- **Breaking**: Remove deprecated `eslint-loader` and add `eslint-webpack-plugin` to presets as `plugins.eslint()`.
- **Potentially Breaking**: Remove `loaders.url()` and `loaders.file()` in favor of Webpack 5 [`asset` modules](https://webpack.js.org/guides/asset-modules/), now usable by including `loaders.asset()` (for assets which can be inlined) and `loaders.resource()` (as a catch-all for other types) in your module rules list. Asset modules are handled automatically in both presets, so this is only breaking if `loaders.url()` or `loaders.file()` was used directly.
- A `webpack-manifest-plugin` instance is now automatically injected in development mode even if `publicPath` is not specified.
- A `webpack-bundle-analyzer` plugin is now automatically added to production builds when Webpack is invoked with the `--analyze` flag.
- Add the [`simple-build-report-webpack-plugin`](https://github.com/kadamwhite/simple-build-report-webpack-plugin) as `plugins.simpleBuildReport()`
- Include a `plugins.simpleBuildReport()` instance in production preset builds to improve legibility of Webpack console output.
- `plugins.fixStyleOnlyEntries()` now uses [`webpack-remove-empty-scripts`](https://github.com/webdiscus/webpack-remove-empty-scripts#webpack-remove-empty-scripts) instead of `webpack-fix-style-only-entries` due to Webpack 5 compatiblity issues with the original plugin.
- Allow `null` to be returned from an `addFilter` callback to skip a loader when using a configuration preset.
- Do not deep merge options passed to `plugins.terserPlugin()`: options object can now fully overwrite `terserOptions` property if needed.
- Permit filtering the Terser default configuration using `addFilter( 'plugins/terser/defaults', cb )`.
- Remove `OptimizeCssAssetsPlugin` (`plugins.optimizeCssAssets()`) in favor of Webpack 5-compatible [CssMinimizerPlugin](https://github.com/webpack-contrib/css-minimizer-webpack-plugin) (`plugins.cssMinimizer()`)
- Remove `plugins.hotModuleReplacement()`, which is now handled automatically by the DevServer in `hot` mode.
- Include the `contenthash` in generated CSS filenames. [#204](https://github.com/humanmade/webpack-helpers/pull/204)

## v0.11.1
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ To make use of this utility, we wrap our development config in a `choosePort` pr
+] );
```

While these bundles are served from memory, now that we've specified a `publicPath`, a new file `asset-manifest.json` will be output into each project's `build/` folder. `themes/myproject/build/asset-manifest.json` will look like this:
While these bundles are served from memory, now that we've specified a `publicPath`, a new file `development-asset-manifest.json` will be output into each project's `build/` folder. `themes/myproject/build/development-asset-manifest.json` will look like this:
```json
{
"frontend.js": "http://localhost:8080/myproject-theme/frontend.js",
Expand All @@ -286,8 +286,8 @@ We use the `cleanOnExit` helper to delete these files when the server shuts down
+
+// Clean up manifests on exit.
+cleanOnExit( [
+ filePath( 'mu-plugins/myproject-blocks/build/asset-manifest.json' ),
+ filePath( 'themes/myproject/build/asset-manifest.json' ),
+ filePath( 'mu-plugins/myproject-blocks/build/development-asset-manifest.json' ),
+ filePath( 'themes/myproject/build/development-asset-manifest.json' ),
+] );
```

Expand Down
70 changes: 70 additions & 0 deletions docs/guides/upgrading-to-v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: Upgrading to v1
parent: Guides
nav_order: 1
---

# Upgrading to v1

## Installation

Install `@humanmade/webpack-helpers@latest` with [npm](http://npmjs.com), along with more updated versions of `webpack` and its attendant dependencies:

```bash
npm install --save-dev @humanmade/webpack-helpers@latest webpack@5 webpack-cli@4 webpack-dev-server@4
```

## Breaking Changes

### Handling multi-config arrays in DevServer

In a large project you may have a Webpack configuration that [exports multiple separate Webpack configuration objects](https://webpack.js.org/configuration/configuration-types/#exporting-multiple-configurations) in an array. The `presets.development()` helper adds a `devServer` property to each generated configuration, and with Webpack 4 and the pre-1.0 version of this helper library this was not a problem: if each entry in an exported array of configurations had its own `devServer` property, DevServer used the configuration in the first item in the exported array and ignored the rest.

In Webpack 5 and the latest DevServer, however, it is an error to define `devServer` properties on any configuration but the first item in the exported array. This means that you may need to map over the exported configurations and unset the `devServer` property on subsequent configurations.

```js
const configs = [
presets.development( { /* ... */ } ),
presets.development( { /* ... */ } ),
presets.development( { /* ... */ } ),
];
module.exports = configs.map( ( config, index ) => {
if ( index > 0 ) {
Reflect.deleteProperty( config, 'devServer' );
}
return config;
} );
```

### Goodbye `filterLoaders`, welcome `addFilter`

Previously, a second argument could be passed to a preset to define a function used to filter loaders used while generating that preset configuration. In v1.0, a [hooks system](https://humanmade.github.io/webpack-helpers/reference/hooks.html) has been introduced which provides an `addFilter` method. `addFilter` can be used to register a callback function that may adjust the value of a loader globally, or make changes specific to a given preset call, in a manner similar to the WordPress PHP hooks system. Read the [hooks reference](https://humanmade.github.io/webpack-helpers/reference/hooks.html), [loaders](https://humanmade.github.io/webpack-helpers/modules/loaders.html), and [preset](https://humanmade.github.io/webpack-helpers/modules/presets.html) documentation pages for more information.

### ESLint v6 and earlier not supported

The ESLint integration for Webpack 5 requires ESLint v7 or later. If your project uses ESLint 6 or before, you will need to upgrade ESLint before using Webpack Helpers 1.0.

```bash
npm install --save-dev eslint@7
```

On most projects ESLint should continue to work after upgrade with no further adjustments.

### Importing named properties from JSON

Due to ongoing changes to how JSON files are handled by Webpack, this code

```js
import { name } from './block.json';
```

may now trigger the error

```
Should not import the named export 'name' (imported as 'name') from default-exporting module (only default export is available soon)
```
This error means that your code above needs to be changed to this:
```js
import blockData from './block.json';
const { name } = blockData;
```
72 changes: 69 additions & 3 deletions docs/modules/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ module.exports = presets.production( {
## `cleanOnExit`


When using the `presets.development()` generator, an `asset-manifest.json` will automatically be generated so long as a `publicPath` URI can be determined. When working with an `asset-manifest.json` file, the `manifest` module provides a `cleanOnExit` method to easily remove manifests once the `webpack-dev-server` shuts down.
When using the `presets.development()` generator, a `development-asset-manifest.json` will automatically be generated so long as a `publicPath` URI can be determined. When working with a `development-asset-manifest.json` file, the `manifest` module provides a `cleanOnExit` method to easily remove manifests once the `webpack-dev-server` shuts down.

```js
const { join } = require( 'path' );
const { helpers } = require( '@humanmade/webpack-helpers' );

helpers.cleanOnExit( [
join( process.cwd(), 'content/mu-plugins/custom-blocks/build/asset-manifest.json' ),
join( process.cwd(), 'content/themes/my-theme/build/asset-manifest.json' ),
join( process.cwd(), 'content/mu-plugins/custom-blocks/build/development-asset-manifest.json' ),
join( process.cwd(), 'content/themes/my-theme/build/development-asset-manifest.json' ),
] );
```

Expand Down Expand Up @@ -98,3 +98,69 @@ module.exports = helpers.choosePort( 9090 ).then( port => [
} ),
] );
```

## Filters

Webpack Helpers v1.0 introduced a new system for altering the behavior of bundled loaders, plugins, and presets, also covered under [Customizing Presets](./presets.html#customizing-presets). This system uses a filtering approach similar to [the way PHP filters work within WordPress](https://developer.wordpress.org/reference/functions/add_filter/), with `addFilter` and `removeFilter` helpers you can use to modify various types of internal data at runtime.

```js
// webpack.config.js
const { helpers } = require( '@humanmade/webpack-helpers' );

const { addFilter, removeFilter } = helpers;

// Hook onto a specific filter by name, and provide a callback function to
// alter the value returned from that filter.
addFilter( 'filter/name', function( value ) {
return 'modified value';
} );

// To filter only some values, you can remove a filter by passing the same
// function reference to removeFilter.
const filterFunction = ( value ) => 'modified value';

addFilter( 'filter/name', filterFunction );

// Do something where the filter gets applied.

removeFilter( 'filter/name', filterFunction );

// Now if you do that same thing, the filter will no longer apply.
```

### Filter List

Each [loader](./loaders.html) exposes at minimum two filters, `loaders/{name}` and `loaders/{name}/defaults`. For example, the defaults for `loaders.ts()` can be filtered using

```js
addFilter( 'loaders/ts/defaults', ( loaderDefaultsObject ) => {
// return a filtered value
} );
```
or the computed final loader object can be modified after the fact with

```js
addFilter( 'loaders/ts', ( loaderObject ) => {
// return a filtered value
} );
```

If you return `null` from the `loaders/{name}` filter, it will remove that loader from the preset entirely.

Additional filters provided by Webpack Helpers:

**`presets/stylesheet-loaders`**

Filter the [stylesheet loader chain](https://webpack.js.org/concepts/loaders/#configuration) used in the `presets.production()` and `presets.development()` helpers. Functions added to this filter receive the stylesheet chain as their first argument, and the name of the compilation mode (`production` or `development`) as the second argument.

**`plugins/terser/defaults`**

Filter the [TerserPlugin default options object](https://webpack.js.org/plugins/terser-webpack-plugin/#options) if you wish to alter the minification settings used by the production preset.

**`loaders/postcss/plugins`**

Filter the list of [PostCSS plugins](https://github.com/postcss/postcss/blob/main/docs/plugins.md) used by the `loaders.postcss()` loader.

**`loaders/postcss/preset-env`**

Filter the [`postcss-preset-env` options](https://github.com/csstools/postcss-preset-env#options) used by the `loaders.postcss()` loader.
37 changes: 25 additions & 12 deletions docs/modules/loaders.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@ nav_order: 3

# Loaders Module

`const { loaders } = require( '@humanmade/webpack-helpers' );`
```js
const { loaders } = require( '@humanmade/webpack-helpers' );
```

This module provides functions that generate configurations for commonly-needed Webpack loaders. Use them within the `.module.rules` array, or use `presets.development()`/`presets.production()` to opt-in to some opinionated defaults.

- `loaders.eslint()`: Return a configured Webpack module loader rule for `eslint-loader`.
- `loaders.js()`: Return a configured Webpack module loader rule for `js-loader`.
- `loaders.ts()`: Return a configured Webpack module loader rule for `ts-loader`.
- `loaders.url()`: Return a configured Webpack module loader rule for `url-loader`.
- `loaders.style()`: Return a configured Webpack module loader rule for `style-loader`.
- `loaders.asset()`: Return a configured Webpack module loader rule for [`asset` modules](https://webpack.js.org/guides/asset-modules/#inlining-assets) which will be inlined when small enough.
- `loaders.css()`: Return a configured Webpack module loader rule for `css-loader`.
- `loaders.js()`: Return a configured Webpack module loader rule for `js-loader`.
- `loaders.postcss()`: Return a configured Webpack module loader rule for `postcss-loader`.
- `loaders.resource()`: Return a configured Webpack module loader rule for [`asset/resource` modules](https://webpack.js.org/guides/asset-modules/#resource-assets).
- `loaders.sass()`: Return a configured Webpack module loader rule for `sass-loader`.
- `loaders.file()`: Return a configured Webpack module loader rule for `file-loader`.
- `loaders.sourcemap()`: Return a configured Webpack module loader rule for `source-map-loader`.
- `loaders.style()`: Return a configured Webpack module loader rule for `style-loader`.
- `loaders.ts()`: Return a configured Webpack module loader rule for `ts-loader`.

The output from these loaders can optionally be [filtered](https://humanmade.github.io/webpack-helpers/reference/hooks.html).

## Customizing Loaders

Expand All @@ -41,16 +45,25 @@ module.exports = {
};
```

To alter the configuration for a loader prior to use within a preset, you may mutate the `.defaults` property on the loader method.
To alter the configuration for a loader prior to use within a preset, you may either [filter](https://humanmade.github.io/webpack-helpers/reference/hooks.html) the default loader options, or the final merged loader configuration.

```js
const { helpers, loaders, presets } = require( '@humanmade/webpack-helpers' );
const { addFilter } = helpers;

// Adjust the loader defaults.
addFilter( 'loaders/js/defaults', ( defaults ) => ( {
...defaults,
include: helpers.filePath( 'themes/my-theme/src' ),
} ) );

// Mutate the loader defaults.
loaders.js.defaults.include = helpers.filePath( 'themes/my-theme/src' );
loaders.css.defaults.options.url = false;
addFilter( 'loaders/css/defaults', ( defaults ) => {
defaults.options.url = false;
return defaults;
} );

// The above customizations will now apply to all calls to loader or preset factories.
module.exports = presets.development( { /* ... */ } );
```

These loaders are also used by the [presets](https://humanmade.github.io/webpack-helpers/modules/presets.html) methods described above. To adjust the behavior of a loader for a specific configuration generated using a preset, you may pass a second argument to the preset defining a filter function which can modify loader options as they are computed. See ["Customizing Presets"](https://humanmade.github.io/webpack-helpers/modules/presets.html#customizing-presets) for more information.
These loaders are also used by the [presets](https://humanmade.github.io/webpack-helpers/modules/presets.html) methods described above. To adjust the behavior of a loader for a specific configuration generated using a preset, see ["Customizing Presets"](https://humanmade.github.io/webpack-helpers/modules/presets.html#customizing-presets).
9 changes: 4 additions & 5 deletions docs/modules/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ This module provides methods which create new instances of commonly-needed Webpa

  | Plugin | Description
------ | ------ | ------------
  | `plugins.bundleAnalyzer()` | Create and return a new [`webpack-bundle-analyzer`](https://github.com/webpack-contrib/webpack-bundle-analyzer) instance. When included this plugin is disabled by default unless the `--analyze` flag is passed on the command line.
  | `plugins.bundleAnalyzer()` | Create and return a new [`webpack-bundle-analyzer`](https://github.com/webpack-contrib/webpack-bundle-analyzer) instance. This plugin is included in production preset builds automatically when the `--analyze` flag is passed on the command line.
  | `plugins.clean()` | Create and return a new [`clean-webpack-plugin`](https://github.com/johnagan/clean-webpack-plugin) instance.
  | `plugins.copy()` | Create and return a new [`copy-webpack-plugin`](https://github.com/webpack-contrib/copy-webpack-plugin) instance.
  | `plugins.errorBell()` | Create and return a new [`bell-on-bundle-error-plugin`](https://www.npmjs.com/package/bell-on-bundler-error-plugin) instance.
  | `plugins.fixStyleOnlyEntries()` | Create and return a [`webpack-fix-style-only-entries`](https://github.com/fqborges/webpack-fix-style-only-entries) instance to remove empty JS bundles for style-only entrypoints.
**D** | `plugins.hotModuleReplacement()` | Create and return a new [`webpack.HotModuleReplacementPlugin`](https://webpack.js.org/plugins/hot-module-replacement-plugin/) instance.
  | `plugins.eslint()` | Create and return a [`eslint-webpack-plugin`](https://webpack.js.org/plugins/eslint-webpack-plugin/) instance.
  | `plugins.fixStyleOnlyEntries()` | Create and return a [`webpack-remove-empty-scripts`](https://github.com/webdiscus/webpack-remove-empty-scripts) instance (forked from the non-Webpack 5-compatible `webpack-fix-style-only-entries`) to remove empty JS bundles for style-only entrypoints.
  | `plugins.manifest()` | : Create and return a new [`webpack-manifest-plugin`](https://github.com/danethurber/webpack-manifest-plugin) instance, preconfigured to write the manifest file while running from a dev server.
**P** | `plugins.miniCssExtract()` | Create and return a new [`mini-css-extract-plugin`](https://github.com/webpack-contrib/mini-css-extract-plugin) instance.
**P** | `plugins.terser()` | Create and return a new [`terser-webpack-plugin`](https://github.com/webpack-contrib/terser-webpack-plugin) instance, preconfigured with defaults based on `create-react-app`.
**P** | `plugins.cssMinimizer()` | Create and return a new [`css-minimizer-webpack-plugin`](https://webpack.js.org/plugins/css-minimizer-webpack-plugin/) instance.

**P**: Included in `presets.production()`

**D**: Included in `presets.development()`
Loading