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

Feature: allow specifying to use before or after other use #42

Merged
merged 3 commits into from
Oct 6, 2017

Conversation

eliperelman
Copy link
Member

No description provided.

Copy link
Member

@edmorley edmorley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea!

Have left a few comments below. I was also wondering whether this functionality would be useful for plugins? eg ScriptExtHtmlPlugin must be after htmlTemplate, which in Neutrino it is by default, but with Treeherder we're needing to add multiple extra htmlTemplate, which end up being placed after ScriptExtHtmlPlugin?

README.md Outdated
@@ -750,6 +750,50 @@ config.module
.options({ presets: ['babel-preset-es2015'] });
```

#### Config module rules use before

Specify to that one `use` should be used before another `use`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this meant to be s/to that/that/ ? (And the same below?)

src/Rule.js Outdated

if (_before && uses.includes(_before)) {
uses.splice(uses.indexOf(name), 1);
uses.splice(Math.max(uses.indexOf(_before), 0), 0, name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the Math.max() needed? presumably the only time it's required is if uses.indexOf(_before) < 0 (eg -1 for not found), however the uses.includes(_before) presumably rules out that case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, this was leftover from a different implementation version.

src/Rule.js Outdated

names.forEach(name => {
const { _before, _after } = useEntries[name];

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a check to ensure both _before and _after are not set for the same rule, and fail loudly if so? (And a mention in the docs?) Since currently if both are set, the _after clobbers the splices made by the _before handling.

README.md Outdated
@@ -750,6 +750,50 @@ config.module
.options({ presets: ['babel-preset-es2015'] });
```

#### Config module rules use before
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other sections use a naming of form "Config module rules uses (loaders): modifying options" - I don't have a preference as to which to use, but wanted to note that this wasn't consistent with them, in case this wasn't intentional.

@eliperelman eliperelman force-pushed the use-before-after branch 4 times, most recently from d397e8f to bcab25a Compare October 5, 2017 16:34
@eliperelman
Copy link
Member Author

@edmorley Great feedback! In order to make ordering more generic for usage with more than uses, I changed quite a bit of this PR. All the tests should still pass, but now the before and after methods can be applied anywhere we like, and are mergeable as well. Also merging should be smarter and less verbose to perform internally after this.

Copy link
Member

@edmorley edmorley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah some good cleanup here now too!

I've left some initial comments - though would like to take another look with fresh eyes once it's updated. If it's not too much of a pain to split it up into say 3 commits (one for the variable name changes, one for adding the omit feature, and one for the before/after handling) that would make review a lot easier, especially given I'm less familiar with the codebase. I use SourceTree for easy line by line commit splitting/staging if that's of any use.

This also has conflicts with the README changes on master, could you rebase? :-)

README.md Outdated
// returns: Object, undefined if empty
entries()
````

```js
// Provide an object which maps its properties and values
// into the backing Map as keys and values.
// into the backing Map as keys and values. Can specify
// an array of keys to omit from the merge.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I read this I was imagining the keys being omitted might be those on the original object (eg so a new array could be passed in for a particular property and not just merged in with the existing array). However from reading the source below the opposite appears to be the case? (I'm struggling at quick glance to tell though due to the larger diff and not having spent long looking at it) Either way I think it would be good to clarify in this comment :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll try to phrase this better. The omit property is supposed to be an array of keys that should be excluded from merging into the config, e.g. the following would do nothing.

config.merge({ devtool: 'source-map' }, ['devtool'])

README.md Outdated
#### Config plugins: ordering before

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/cannot use/cannot use both/ perhaps? (And in the other instances below)


config
.plugin('html-template')
.use(HtmlWebpackTemplate)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation here is inconsistent with some of the other existing entries - this indents the .use() one level deeper than .plugin(), the others don't. Thoughts on which is preferred?


after(name) {
if (this.__after) {
throw new Error(`Unable to set after(${JSON.stringify(name)}) with existing value for before`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be after(...) or .after(...) ? (And same for before(...))

I can't decide :-)


merge(obj, omit = []) {
if (obj.before && obj.after) {
throw new Error(`Unable to merge before: ${JSON.stringify(obj.before)} and after: ${JSON.stringify(obj.after)} on the same object`);
Copy link
Member

@edmorley edmorley Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this case ever be hit given there are already checks at the time of using before() and after()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, when merging in configuration from an object, these can be set by the user:

config.merge({
  module: {
    rule: {
      compile: {
        use: {
          cache: {
            loader: 'cache-loader',
            before: 'babel'
          }
        }
      }
    }
  }
})

@@ -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) {
Copy link
Member

@edmorley edmorley Oct 5, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be in a separate cleanup commit in the PR :-)

@@ -53,8 +74,23 @@ module.exports = class extends Chainable {
return this;
}

merge(obj) {
Object.keys(obj).forEach(key => this.set(key, obj[key]));
merge(obj, omit = []) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and the other merge/omit parts could be a separate commit in the PR from the before/after parts :-)

src/Plugin.js Outdated
@@ -28,12 +28,12 @@ module.exports = class extends ChainedMap {
this.set('args', obj.args);
}

return this;
return super.merge(obj, [...omit, 'args', 'plugin'])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon.

I wonder if we should add some linting to this repo?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I've put it off for a while. I can do that in another PR, although it would be easier to either use Neutrino (seems circular) or move this repo into the monorepo.

test/Rule.js Outdated
]
});
});

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test for the "before and after aren't allowed at the same time" handling?

I think we also need some tests for all of the merge omit functionality?

@eliperelman eliperelman force-pushed the use-before-after branch 2 times, most recently from 6c7ae12 to a9f8f37 Compare October 6, 2017 00:24
@eliperelman
Copy link
Member Author

OK, I think I got everything addressed. Thank you for the in-depth review!

Copy link
Member

@edmorley edmorley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thank you for adding the extra tests :-)

README.md Outdated
@@ -201,8 +201,11 @@ 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 to the second argument
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/an array to the second argument/an array as the second argument/ maybe? Up to you :-)

README.md Outdated
#### Config resolve plugins: ordering after

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/cannot use/cannot use both/

src/Rule.js Outdated
if (!omit.includes('oneOf') && 'oneOf' in obj) {
Object
.keys(obj.oneOf)
.forEach(name => this.oneOf(name).merge(obj.oneOf[name]))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon

README.md Outdated
@@ -194,6 +193,8 @@ 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 also
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/also// ? Though happy for you to pick

README.md Outdated

// Example

config.resolve.plugin('beta')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The non-resolve examples and also the config.resolve "after" example below, put the .plugin() on a new line, so I think this should be too?

src/Orderable.js Outdated
module.exports = (Class) => class extends Class {
before(name) {
if (this.__after) {
throw new Error(`Unable to set .before(${JSON.stringify(name)}) with existing value for after`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the with existing value for after part need quotes or something around the "after", to make it clearer? (Or else .after() ?)

(And same for below)

@eliperelman
Copy link
Member Author

Accepted all your requests.

@eliperelman eliperelman merged commit 8dc5e34 into neutrinojs:master Oct 6, 2017
@eliperelman
Copy link
Member Author

🎉

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants