Skip to content
This repository was archived by the owner on Feb 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #42 from eliperelman/use-before-after
Browse files Browse the repository at this point in the history
Feature: allow specifying to use before or after other use
  • Loading branch information
eliperelman authored Oct 6, 2017
2 parents a669fe0 + b0040bf commit 8dc5e34
Show file tree
Hide file tree
Showing 17 changed files with 476 additions and 191 deletions.
106 changes: 97 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ config
.entry('index')
.add('src/index.js')
.end()

// Modify output settings
.output
.path('dist')
Expand Down Expand Up @@ -194,25 +193,30 @@ values()
// where the key is the object property, and the value
// corresponding to the key. Will return `undefined` if the backing
// Map is empty.
// This will order properties by their name if the value is
// a ChainedMap that used .before() or .after().
// returns: Object, undefined if empty
entries()
````

```js
// Provide an object which maps its properties and values
// into the backing Map as keys and values.
// You can also provide an array as the second argument
// for property names to omit from being merged.
// obj: Object
merge(obj)
// omit: Optional Array
merge(obj, omit)
```

```js
// Conditionally execute a function to continue configuration
// condition: Boolean
// truthyHandler: Function -> ChainedMap
// whenTruthy: Function -> ChainedMap
// invoked when condition is truthy, given a single argument of the ChainedMap instance
// falsyHandler: Function -> ChainedMap
// whenFalsy: Optional Function -> ChainedMap
// invoked when condition is falsy, given a single argument of the ChainedMap instance
when(condition, truthyHandler, falsyHandler)
when(condition, whenTruthy, whenFalsy)
```

## ChainedSet
Expand Down Expand Up @@ -269,11 +273,11 @@ merge(arr)
```js
// Conditionally execute a function to continue configuration
// condition: Boolean
// truthyHandler: Function -> ChainedSet
// whenTruthy: Function -> ChainedSet
// invoked when condition is truthy, given a single argument of the ChainedSet instance
// falsyHandler: Function -> ChainedSet
// whenFalsy: Optional Function -> ChainedSet
// invoked when condition is falsy, given a single argument of the ChainedSet instance
when(condition, truthyHandler, falsyHandler)
when(condition, whenTruthy, whenFalsy)
```

## Shorthand methods
Expand Down Expand Up @@ -353,7 +357,7 @@ config
config
.entry(name)
.clear()
.clear()
// Using low-level config.entryPoints:
Expand Down Expand Up @@ -608,6 +612,48 @@ config
config.plugins.delete(name)
```

#### Config plugins: ordering before

Specify that the current `plugin` context should operate before another named `plugin`.
You cannot use both `.before()` and `.after()` on the same plugin.

```js
config
.plugin(name)
.before(otherName)
// Example
config
.plugin('html-template')
.use(HtmlWebpackTemplate)
.end()
.plugin('script-ext')
.use(ScriptExtWebpackPlugin)
.before('html-template');
```

#### Config plugins: ordering after

Specify that the current `plugin` context should operate after another named `plugin`.
You cannot use both `.before()` and `.after()` on the same plugin.

```js
config
.plugin(name)
.after(otherName)
// Example
config
.plugin('html-template')
.after('script-ext')
.use(HtmlWebpackTemplate)
.end()
.plugin('script-ext')
.use(ScriptExtWebpackPlugin);
```

#### Config resolve plugins

```js
Expand Down Expand Up @@ -647,6 +693,48 @@ config.resolve
config.resolve.plugins.delete(name)
```

#### Config resolve plugins: ordering before

Specify that the current `plugin` context should operate before another named `plugin`.
You cannot use both `.before()` and `.after()` on the same resolve plugin.

```js
config.resolve
.plugin(name)
.before(otherName)
// Example
config.resolve
.plugin('beta')
.use(BetaWebpackPlugin)
.end()
.plugin('alpha')
.use(AlphaWebpackPlugin)
.before('beta');
```

#### Config resolve plugins: ordering after

Specify that the current `plugin` context should operate after another named `plugin`.
You cannot use both `.before()` and `.after()` on the same resolve plugin.

```js
config.resolve
.plugin(name)
.after(otherName)
// Example
config.resolve
.plugin('beta')
.after('alpha')
.use(BetaWebpackTemplate)
.end()
.plugin('alpha')
.use(AlphaWebpackPlugin);
```

#### Config node

```js
Expand Down
65 changes: 51 additions & 14 deletions src/ChainedMap.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const merge = require('deepmerge');
const Chainable = require('./Chainable');

module.exports = class extends Chainable {
Expand All @@ -11,6 +12,7 @@ module.exports = class extends Chainable {
methods.map(method => {
this[method] = value => this.set(method, value);
});
return this;
}

clear() {
Expand All @@ -23,21 +25,41 @@ module.exports = class extends Chainable {
return this;
}

entries() {
const entries = [...this.store];

if (!entries.length) {
return;
}

return entries.reduce((acc, [key, value]) => {
order() {
const entries = [...this.store].reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
const names = Object.keys(entries);
const order = [...names];

names.forEach(name => {
const { __before, __after } = entries[name];

if (__before && order.includes(__before)) {
order.splice(order.indexOf(name), 1);
order.splice(order.indexOf(__before), 0, name);
} else if (__after && order.includes(__after)) {
order.splice(order.indexOf(name), 1);
order.splice(order.indexOf(__after) + 1, 0, name);
}
});

return { entries, order };
}

entries() {
const { entries, order } = this.order();

if (order.length) {
return entries;
}
}

values() {
return [...this.store.values()];
const { entries, order } = this.order();

return order.map(name => entries[name]);
}

get(key) {
Expand All @@ -53,8 +75,23 @@ module.exports = class extends Chainable {
return this;
}

merge(obj) {
Object.keys(obj).forEach(key => this.set(key, obj[key]));
merge(obj, omit = []) {
Object
.keys(obj)
.forEach(key => {
if (omit.includes(key)) {
return;
}

const value = obj[key];

if ((!Array.isArray(value) && typeof value !== 'object') || value === null || !this.has(key)) {
this.set(key, value);
} else {
this.set(key, merge(this.get(key), value));
}
});

return this;
}

Expand Down Expand Up @@ -82,11 +119,11 @@ module.exports = class extends Chainable {
}, {});
}

when(condition, trueBrancher = Function.prototype, falseBrancher = Function.prototype) {
when(condition, whenTruthy = Function.prototype, whenFalsy = Function.prototype) {
if (condition) {
trueBrancher(this);
whenTruthy(this);
} else {
falseBrancher(this);
whenFalsy(this);
}

return this;
Expand Down
6 changes: 3 additions & 3 deletions src/ChainedSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ module.exports = class extends Chainable {
return this;
}

when(condition, trueBrancher = Function.prototype, falseBrancher = Function.prototype) {
when(condition, whenTruthy = Function.prototype, whenFalsy = Function.prototype) {
if (condition) {
trueBrancher(this);
whenTruthy(this);
} else {
falseBrancher(this);
whenFalsy(this);
}

return this;
Expand Down
58 changes: 26 additions & 32 deletions src/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,41 +74,35 @@ module.exports = class extends ChainedMap {
}));
}

merge(obj = {}) {
Object
.keys(obj)
.forEach(key => {
const value = obj[key];
merge(obj = {}, omit = []) {
const omissions = [
'node',
'output',
'resolve',
'resolveLoader',
'devServer',
'performance',
'module'
];

switch (key) {
case 'node':
case 'output':
case 'resolve':
case 'resolveLoader':
case 'devServer':
case 'performance':
case 'module': {
return this[key].merge(value);
}

case 'entry': {
return Object
.keys(value)
.forEach(name => this.entry(name).merge(value[name]));
}
if (!omit.includes('entry') && 'entry' in obj) {
Object
.keys(obj.entry)
.forEach(name => this.entry(name).merge(obj.entry[name]));
}

case 'plugin': {
return Object
.keys(value)
.forEach(name => this.plugin(name).merge(value[name]));
}
if (!omit.includes('plugin') && 'plugin' in obj) {
Object
.keys(obj.plugin)
.forEach(name => this.plugin(name).merge(obj.plugin[name]));
}

default: {
this.set(key, value);
}
}
});
omissions.forEach(key => {
if (!omit.includes(key) && key in obj) {
this[key].merge(obj[key]);
}
});

return this;
return super.merge(obj, [...omit, ...omissions, 'entry', 'plugin']);
}
};
26 changes: 5 additions & 21 deletions src/DevServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,11 @@ module.exports = class extends ChainedMap {
}, this.entries() || {}));
}

merge(obj) {
Object
.keys(obj)
.forEach(key => {
const value = obj[key];
merge(obj, omit = []) {
if (!omit.includes('allowedHosts') && 'allowedHosts' in obj) {
this.allowedHosts.merge(obj.allowedHosts);
}

switch (key) {
case 'allowedHosts': {
return this[key].merge(value);
}

default: {
if (this.has(key)) {
this.set(key, merge(this.get(key), value));
} else {
this.set(key, value);
}
}
}
});

return this;
return super.merge(obj, ['allowedHosts']);
}
};
Loading

0 comments on commit 8dc5e34

Please sign in to comment.