Skip to content

Commit 6b8779c

Browse files
committed
Update readme for version 2
1 parent 7f4e113 commit 6b8779c

File tree

1 file changed

+230
-6
lines changed

1 file changed

+230
-6
lines changed

README.md

+230-6
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ Provides a cleaner API for enabling and configuring plugins for [next.js](https:
55
It is often unclear which plugins are enabled or which configuration belongs to which plugin because they are nested and share one configuration object.
66
This can also lead to orphaned configuration values when updating or removing plugins.
77

8-
`next-compose-plugins` tries to eliminate this case by providing an alternative API for enabling and configuring plugins where each plugin has their own configuration object.
8+
While `next-compose-plugins` tries to eliminate this case by providing an alternative API for enabling and configuring plugins where each plugin has their own configuration object, it also adds more features like phase specific plugins and configuration.
99

1010
## Table of contents
1111

1212
- [Installation](#installation)
1313
- [Usage](#usage)
14-
- [Example](#example)
14+
- [Plugin developers](#plugin-developers)
15+
- [Examples](#examples)
1516
- [See also](#see-also)
1617
- [License](#license)
1718

@@ -21,6 +22,9 @@ This can also lead to orphaned configuration values when updating or removing pl
2122
npm install --save next-compose-plugins
2223
```
2324

25+
This plugin requires next.js `>= 5.1` because it depends on the phases introduced within this version.
26+
If you are still on `5.0.x`, you can install v1 of this plugin: `npm install --save next-compose-plugins@1`.
27+
2428
## Usage
2529
```javascript
2630
// next.config.js
@@ -31,15 +35,178 @@ module.exports = withPlugins([...plugins], nextConfiguration);
3135

3236
### `plugins`
3337

34-
Is an array containing all plugins and their configuration.
38+
> See the [examples](#examples) for more use-cases.
39+
40+
It is an array containing all plugins and their configuration.
3541
If a plugin does not need additional configuration, you can simply add the imported plugin.
36-
If it does need configuration, you can specify an array where the first element is the plugin and the second its configuration: `[sass, {mySassConfig: 'foobar'}]` (see [example](#example)).
42+
If it does need configuration or you only want to run it in a specific phase, you can specify an array:
43+
44+
#### `[plugin: function, configuration?: object, phases?: array]`
45+
46+
##### `plugin: function`
47+
48+
Imported plugin.
49+
See the [optional plugins](#optional-plugins) section if you only want to require a plugin when it is really used.
50+
51+
```javascript
52+
const withPlugins = require('next-compose-plugins');
53+
const sass = require('@zeit/next-sass');
54+
55+
module.exports = withPlugins([
56+
[sass],
57+
]);
58+
```
59+
60+
##### `configuration?: object`
61+
62+
Configuration for the plugin.
63+
64+
You can also overwrite specific configuration keys for a phase:
65+
66+
```javascript
67+
const withPlugins = require('next-compose-plugins');
68+
const { PHASE_PRODUCTION_BUILD } = require('next/constants');
69+
const sass = require('@zeit/next-sass');
70+
71+
module.exports = withPlugins([
72+
[sass, {
73+
cssModules: true,
74+
cssLoaderOptions: {
75+
localIdentName: '[path]___[local]___[hash:base64:5]',
76+
},
77+
[PHASE_PRODUCTION_BUILD]: {
78+
cssLoaderOptions: {
79+
localIdentName: '[hash:base64:8]',
80+
},
81+
},
82+
}],
83+
]);
84+
```
85+
86+
This will overwrite the `cssLoaderOptions` with the new `localIdentName` specified, but **only** during production build.
87+
You can also combine multiple phases (`[PHASE_PRODUCTION_BUILD + PHASE_PRODUCTION_SERVER]: {}`) or exclude a phase (`['!' + PHASE_PRODUCTION_BUILD]: {}` which will overwrite the config in all phases except `PRODUCTION_BUILD`).
88+
You can use all phases [next.js provides](https://github.com/zeit/next.js/blob/canary/lib/constants.js).
89+
90+
##### `phases?: array`
91+
92+
If the plugin should only be applied in specific phases, you can specify them here.
93+
You can use all phases [next.js provides](https://github.com/zeit/next.js/blob/canary/lib/constants.js).
94+
95+
```javascript
96+
const withPlugins = require('next-compose-plugins');
97+
const { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } = require('next/constants');
98+
const sass = require('@zeit/next-sass');
99+
100+
module.exports = withPlugins([
101+
[sass, {
102+
cssModules: true,
103+
cssLoaderOptions: {
104+
localIdentName: '[path]___[local]___[hash:base64:5]',
105+
},
106+
}, [PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD]],
107+
]);
108+
```
109+
110+
You can also negate the phases with a leading `!`:
111+
112+
```javascript
113+
const withPlugins = require('next-compose-plugins');
114+
const { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } = require('next/constants');
115+
const sass = require('@zeit/next-sass');
116+
117+
module.exports = withPlugins([
118+
[sass, {
119+
cssModules: true,
120+
cssLoaderOptions: {
121+
localIdentName: '[path]___[local]___[hash:base64:5]',
122+
},
123+
}, ['!', PHASE_DEVELOPMENT_SERVER]],
124+
]);
125+
```
126+
127+
This will apply the plugin in all phases except `PHASE_DEVELOPMENT_SERVER`.
37128

38129
### `nextConfiguration`
39130

40131
Any direct [next.js configuration](https://github.com/zeit/next.js#custom-configuration) can go here, for example: `{distDir: 'dist'}`.
41132

42-
## Example
133+
### Optional plugins
134+
135+
If a plugin should only get loaded when it is used, you can use the `optional` helper function.
136+
This can be useful if the plugin is only in the `devDependencies` and so you only want to apply it during `PHASE_DEVELOPMENT_SERVER`.
137+
If you don't use the `optional` helper in this case, you would get an error.
138+
139+
```javascript
140+
const { withPlugins, optional } = require('next-compose-plugins');
141+
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');
142+
143+
module.exports = withPlugins([
144+
[optional(() => require('@zeit/next-sass')), { /* optional configuration */ }, [PHASE_DEVELOPMENT_SERVER]],
145+
]);
146+
```
147+
148+
## Plugin developers
149+
150+
This plugin has a few extra functionality which you can use as a plugin developer.
151+
However, if you use them, you should mention somewhere in your readme or install instructions that it needs `next-compose-plugins` to have all features available and so it won't confuse your users if something is not working as described out-of-the-box because they don't use this compose plugin yet.
152+
153+
### Phases
154+
155+
You can specify in which phases your plugin should get executed within the object you return:
156+
157+
```javascript
158+
const { PHASE_DEVELOPMENT_SERVER } = require('next/constants');
159+
160+
module.exports = (nextConfig = {}) => {
161+
return Object.assign({}, nextConfig, {
162+
// define in which phases this plugin should get applied.
163+
// you can also use multiple phases or negate them.
164+
// however, users can still overwrite them in their configuration if they really want to.
165+
phases: [PHASE_DEVELOPMENT_SERVER],
166+
167+
webpack(config, options) {
168+
// do something here which only gets applied during development server phase
169+
170+
if (typeof nextConfig.webpack === 'function') {
171+
return nextConfig.webpack(config, options);
172+
}
173+
174+
return config;
175+
},
176+
};
177+
};
178+
```
179+
180+
These phases are handled as a default configuration and users can overwrite the phases in their `next.config.js` file if they want to.
181+
See [phases configuration](#phases-array) for all available options.
182+
183+
### Additional information
184+
185+
When a plugin gets loaded with `next-compose-plugins`, some additional information on which you can depend is available.
186+
It gets passed in as the second argument to your plugin function:
187+
188+
```javascript
189+
module.exports = (nextConfig = {}, nextComposePlugins = {}) => {
190+
console.log(nextComposePlugins);
191+
};
192+
```
193+
194+
Currently, it contains these values:
195+
196+
```javascript
197+
{
198+
// this is always true when next-compose-plugins is used
199+
// so you can use this as a check when your plugin depends on it
200+
nextComposePlugins: boolean,
201+
202+
// the current phase which gets applied
203+
phase: string,
204+
}
205+
```
206+
207+
## Examples
208+
209+
### Basic example
43210
44211
```javascript
45212
// next.config.js
@@ -78,7 +245,64 @@ module.exports = withPlugins([
78245
], nextConfig);
79246
```
80247
81-
As a comparison, it would look like this without this plugin where it is not really clear which configuration belongs to which plugin and what are all the enabled plugins:
248+
### Advanced example
249+
250+
```javascript
251+
// next.config.js
252+
const { withPlugins, optional } = require('next-compose-plugins');
253+
const images = require('next-images');
254+
const sass = require('@zeit/next-sass');
255+
const typescript = require('@zeit/next-typescript');
256+
257+
const {
258+
PHASE_PRODUCTION_BUILD,
259+
PHASE_PRODUCTION_SERVER,
260+
PHASE_DEVELOPMENT_SERVER,
261+
PHASE_EXPORT,
262+
} = require('next/constants');
263+
264+
// next.js configuration
265+
const nextConfig = {
266+
useFileSystemPublicRoutes: false,
267+
distDir: 'build',
268+
};
269+
270+
module.exports = withPlugins([
271+
272+
// add a plugin with specific configuration
273+
[sass, {
274+
cssModules: true,
275+
cssLoaderOptions: {
276+
importLoaders: 1,
277+
localIdentName: '[local]___[hash:base64:5]',
278+
},
279+
[PHASE_PRODUCTION_BUILD + PHASE_EXPORT]: {
280+
cssLoaderOptions: {
281+
importLoaders: 1,
282+
localIdentName: '[hash:base64:8]',
283+
},
284+
},
285+
}],
286+
287+
// add a plugin without a configuration
288+
images,
289+
290+
// another plugin with a configuration (applied in all phases except development server)
291+
[typescript, {
292+
typescriptLoaderOptions: {
293+
transpileOnly: false,
294+
},
295+
}, ['!', PHASE_DEVELOPMENT_SERVER]],
296+
297+
// load and apply a plugin only during development server phase
298+
[optional(() => require('@some-internal/dev-log')), [PHASE_DEVELOPMENT_SERVER]],
299+
300+
], nextConfig);
301+
```
302+
303+
### Comparison
304+
305+
As a comparison, it would look like this without this plugin where it is not really clear which configuration belongs to which plugin and what are all the enabled plugins. Many features mentioned above will also not be possible or requires you to have a lot more custom code in your config file.
82306
83307
```javascript
84308
// next.config.js

0 commit comments

Comments
 (0)