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

Commit

Permalink
Add rule.rules
Browse files Browse the repository at this point in the history
  • Loading branch information
opl- committed Dec 19, 2019
1 parent 7fb3c67 commit 49a93c2
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 1 deletion.
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,93 @@ config.module
}));
```

#### Config module rules nested rules:

```js
config.module.rules{}.rules : ChainedMap<Rule>
config.module
.rule(name)
.rule(name)
// Example
config.module
.rule('css')
.test(/\.css$/)
.use('style')
.loader('style-loader')
.end()
.rule('postcss')
.resourceQuery(/postcss/)
.use('postcss')
.loader('postcss-loader')
```

#### Config module rules nested rules: ordering before
Specify that the current `rule` context should operate before another named
`rule`. You cannot use both `.before()` and `.after()` on the same `rule`.

```js
config.module.rules{}.rules : ChainedMap<Rule>
config.module
.rule(name)
.rule(name)
.before(otherName)
// Example
config.module
.rule('css')
.use('style')
.loader('style-loader')
.end()
.rule('postcss')
.resourceQuery(/postcss/)
.use('postcss')
.loader('postcss-loader')
.end()
.end()
.rule('css-loader')
.resourceQuery(/css-loader/)
.before('postcss')
.use('css-loader')
.loader('css-loader')
```

#### Config module rules nested rules: ordering after
Specify that the current `rule` context should operate after another named
`rule`. You cannot use both `.before()` and `.after()` on the same `rule`.

```js
config.module.rules{}.rules : ChainedMap<Rule>
config.module
.rule(name)
.rule(name)
.after(otherName)
// Example
config.module
.rule('css')
.use('style')
.loader('style-loader')
.end()
.rule('postcss')
.resourceQuery(/postcss/)
.after('css-loader')
.use('postcss')
.loader('postcss-loader')
.end()
.end()
.rule('css-loader')
.resourceQuery(/css-loader/)
.use('css-loader')
.loader('css-loader')
```

#### Config module rules oneOfs (conditional rules):

```js
Expand Down Expand Up @@ -1233,6 +1320,10 @@ config.merge({
include: [...paths],
exclude: [...paths],
rules: {
[name]: Rule
},
oneOf: {
[name]: Rule
},
Expand Down
13 changes: 13 additions & 0 deletions src/Rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const Rule = Orderable(
this.uses = new ChainedMap(this);
this.include = new ChainedSet(this);
this.exclude = new ChainedSet(this);
this.rules = new ChainedMap(this);
this.oneOfs = new ChainedMap(this);
this.extend([
'enforce',
Expand All @@ -36,6 +37,10 @@ const Rule = Orderable(
return this.uses.getOrCompute(name, () => new Use(this, name));
}

rule(name) {
return this.rules.getOrCompute(name, () => new Rule(this, name));
}

oneOf(name) {
return this.oneOfs.getOrCompute(name, () => new Rule(this, name));
}
Expand All @@ -53,6 +58,7 @@ const Rule = Orderable(
Object.assign(this.entries() || {}, {
include: this.include.values(),
exclude: this.exclude.values(),
rules: this.rules.values().map(rule => rule.toConfig()),
oneOf: this.oneOfs.values().map(oneOf => oneOf.toConfig()),
use: this.uses.values().map(use => use.toConfig()),
}),
Expand Down Expand Up @@ -80,6 +86,12 @@ const Rule = Orderable(
);
}

if (!omit.includes('rules') && 'rules' in obj) {
Object.keys(obj.rules).forEach(name =>
this.rule(name).merge(obj.rules[name]),
);
}

if (!omit.includes('oneOf') && 'oneOf' in obj) {
Object.keys(obj.oneOf).forEach(name =>
this.oneOf(name).merge(obj.oneOf[name]),
Expand All @@ -99,6 +111,7 @@ const Rule = Orderable(
'include',
'exclude',
'use',
'rules',
'oneOf',
'test',
]);
Expand Down
102 changes: 101 additions & 1 deletion test/Rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ test('use', t => {
t.true(rule.uses.has('babel'));
});

test('rule', t => {
const rule = new Rule();
const instance = rule.rule('babel').end();

t.is(instance, rule);
t.true(rule.rules.has('babel'));
});

test('oneOf', t => {
const rule = new Rule();
const instance = rule.oneOf('babel').end();
Expand Down Expand Up @@ -100,6 +108,12 @@ test('toConfig with values', t => {
.loader('babel-loader')
.options({ presets: ['alpha'] })
.end()
.rule('minifier')
.resourceQuery(/minify/)
.use('minifier')
.loader('minifier-loader')
.end()
.end()
.oneOf('inline')
.resourceQuery(/inline/)
.use('url')
Expand All @@ -110,6 +124,16 @@ test('toConfig with values', t => {
enforce: 'pre',
include: ['alpha', 'beta'],
exclude: ['alpha', 'beta'],
rules: [
{
resourceQuery: /minify/,
use: [
{
loader: 'minifier-loader',
},
],
},
],
oneOf: [
{
resourceQuery: /inline/,
Expand Down Expand Up @@ -147,6 +171,16 @@ test('merge empty', t => {
test: /\.js$/,
include: ['alpha', 'beta'],
exclude: ['alpha', 'beta'],
rules: {
minifier: {
resourceQuery: /minify/,
use: {
minifier: {
loader: 'minifier-loader',
},
},
},
},
oneOf: {
inline: {
resourceQuery: /inline/,
Expand Down Expand Up @@ -174,6 +208,16 @@ test('merge empty', t => {
test: /\.js$/,
include: ['alpha', 'beta'],
exclude: ['alpha', 'beta'],
rules: [
{
resourceQuery: /minify/,
use: [
{
loader: 'minifier-loader',
},
],
},
],
oneOf: [
{
resourceQuery: /inline/,
Expand Down Expand Up @@ -213,6 +257,16 @@ test('merge with values', t => {
enforce: 'pre',
include: ['alpha', 'beta'],
exclude: ['alpha', 'beta'],
rules: {
minifier: {
resourceQuery: /minify/,
use: {
minifier: {
loader: 'minifier-loader',
},
},
},
},
oneOf: {
inline: {
resourceQuery: /inline/,
Expand All @@ -237,6 +291,16 @@ test('merge with values', t => {
enforce: 'pre',
include: ['gamma', 'delta', 'alpha', 'beta'],
exclude: ['alpha', 'beta'],
rules: [
{
resourceQuery: /minify/,
use: [
{
loader: 'minifier-loader',
},
],
},
],
oneOf: [
{
resourceQuery: /inline/,
Expand Down Expand Up @@ -277,6 +341,16 @@ test('merge with omit', t => {
enforce: 'pre',
include: ['alpha', 'beta'],
exclude: ['alpha', 'beta'],
rules: {
minifier: {
resourceQuery: /minify/,
use: {
minifier: {
loader: 'minifier-loader',
},
},
},
},
oneOf: {
inline: {
resourceQuery: /inline/,
Expand All @@ -295,7 +369,7 @@ test('merge with omit', t => {
},
},
},
['use', 'oneOf'],
['use', 'oneOf', 'rules'],
);

t.deepEqual(rule.toConfig(), {
Expand All @@ -314,6 +388,32 @@ test('merge with omit', t => {
});
});

test('ordered rules', t => {
const rule = new Rule();
rule
.rule('first')
.test(/\.first$/)
.end()
.rule('second')
.test(/\.second$/)
.end()
.rule('third')
.test(/\.third$/)
.end()
.rule('alpha')
.test(/\.alpha$/)
.before('first')
.end()
.rule('beta')
.test(/\.beta$/)
.after('second');

t.deepEqual(
rule.toConfig().rules.map(o => o.test),
[/\.alpha$/, /\.first$/, /\.second$/, /\.beta$/, /\.third$/],
);
});

test('ordered oneOfs', t => {
const rule = new Rule();
rule
Expand Down
2 changes: 2 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ declare namespace Config {
}

class Rule<T = Module> extends ChainedMap<T> implements Orderable {
rules: TypedChainedMap<this, Rule<Rule>>;
oneOfs: TypedChainedMap<this, Rule<Rule>>;
uses: TypedChainedMap<this, Use>;
include: TypedChainedSet<this, webpack.Condition>;
Expand All @@ -218,6 +219,7 @@ declare namespace Config {
enforce(value: 'pre' | 'post'): this;

use(name: string): Use<this>;
rule(name: string): Rule<Rule>;
oneOf(name: string): Rule<Rule>;
pre(): this;
post(): this;
Expand Down
10 changes: 10 additions & 0 deletions types/test/webpack-chain-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,16 @@ config
.end()
.pre()
.post()
.rule('inline')
.after('vue')
.resourceQuery(/inline/)
.use('url')
.loader('url-loader')
.end()
.end()
.rules
.delete('inline')
.end()
.oneOf('inline')
.after('vue')
.uses
Expand Down

0 comments on commit 49a93c2

Please sign in to comment.