-
-
Notifications
You must be signed in to change notification settings - Fork 105
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
Make constructor set custom properties #92
Conversation
@@ -141,6 +144,12 @@ File.prototype.inspect = function() { | |||
return '<File ' + inspect.join(' ') + '>'; | |||
}; | |||
|
|||
File.builtInFields = ['_contents', 'contents', 'stat', 'history', 'path', 'base', 'cwd']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this should be exposed on the constructor. Not sure of a better way to do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to suggestions. My main concern is for it to be configurable on objects that extend from Vinyl
. With this implementation you can just do:
class Vinyl2 extends Vinyl {}
Vinyl2.builtInFields = ['foo', 'bar', ...Vinyl2.builtInFields];
And everything works as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a second argument to the constructor? Not sure though
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll just chime in and say that exposing it as a static property on the File
constructor is my preferred solution. It is a clean way for supporting other solutions that extend Vinyl
as is demonstrated here. If it was added to the prototype
, it would have to be stepped around during clone and such to prevent clobbering. However, adding it as an argument to the constructor itself would require a sub-class to specify those additional args on each instance. Depending on how it's done, that becomes an extra burden to either the devs or the consumers. (not to mention having tons of duplicate arrays floating around in memory)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can't be 2nd argument to the constructor, as that would imply it's upon user to decide what is a built in property, while this decision is 100% decided by the current virtual object implementation.
The alternative can be just a file scoped variable not exposed to the user:
var builtInFields = ['_contents', 'contents', 'stat', 'history', 'path', 'base', 'cwd'];
File.isCustomProp = function(key) {
return builtInFields.indexOf(key) === -1;
};
And anyone that extends Vinyl
will just extend the method as needed:
class Vinyl2 extends Vinyl {
static isCustomProp(key) {
return super.isCustomProp(key) && ['my', 'own', 'props'].indexOf(key) === -1;
}
}
I'd actually even prefer this as this way we won't have to be juggling configs on constructor properties.
Can we move forward on this? I have path normalization PR in the works (to resolve #80), with tests rewrite so they pass on windows, but it requires |
Won't be able to look at this for awhile. Real life... |
@darsain are you going to make the changes to inline the built-in fields into the |
This is perfect! Would love to get this merged and released soon if possible. |
I'd wait with the release for my next PR, which will normalize paths so they don't cause issues on windows. Even Vinyl's own tests don't pass on windows because of that. But I need this merged before I finish it, so I'm not working/submitting over merge conflicts. |
|
||
// Set custom properties | ||
Object.keys(file).forEach(function(key) { | ||
if (this.constructor.isCustomProp(key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be checked to be a function before calling it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'll always be a function, since extends
inherits static methods as well. It'd be the same as checking if file.isBuffer()
is a function. Of course it is if it inherits from Vinyl :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Example:
function Foo() {}
Foo.prototype.check = function () {
console.log(this.constructor.stat());
};
Foo.stat = function () {
return 'foo';
};
class Bar extends Foo {}
class Baz extends Foo {
static stat() {
return 'baz';
}
}
new Foo().check(); // foo
new Bar().check(); // foo
new Baz().check(); // baz
@darsain just realized I forgot about this PR. It looks good but needs docs. |
Will this do? |
Yeah, those look good. |
Published this and your previous change as 1.2.0 |
Cool. Needed this to get merged to start working on path normalization PR. Hopefully I'll get to it tomorrow :) |
@darsain awesome. I'll probably be very nitpick-y about the normalization stuff because we've had a few problems recently - see: https://github.com/gulpjs/vinyl-fs/blob/master/lib/prepare-write.js#L47-L49 which needs to be moved into vinyl and most of the path stuff needs to be normalized (e.g. directory returning properties should always end in a keep up the great work! |
Currently, when doing this:
sourceMap
and any other custom properties are ignored. This PR will make constructor extendthis
with all custom props passed in the configuration object.It'll make creating Vinyl files a bit faster and more comfy.
I'm also moving check for custom properties from that multiline
if
statement to a dedicated static methodFile.isCustomProp(key)
which relies onFile.builtInFields
array to check if a key is a custom property.This is than used in
#clone()
, as well as constructor, and could be used in#toJSON()
method from other PR.It also allows anyone that extends from
Vinyl
to extend theirExtendedVinyl.builtInFields
with their own props that shouldn't be cloned.