Closed LeaVerou closed 6 months ago
- A
Treecle
class. This is the most obvious option for facilitating different configurations, however it will be a pain to facilitate tree-shaking with it (we'd need to support both the separate functions and the class, and write the function code in such a way that it works for both (e.g.let myConfig = this.config ?? config
).
Can you explain a little more on tree shaking? If there's a way to make this work, I think this is the best option by far. We can have a Treecle class, and it has a bunch of static methods (implementing all of the tree functionality), and it can have instance variables for the config, which it tries to use if they're set and otherwise falls back to the default ones, that way you could do either Treecle.transform(...) // uses default settings
or
const treecle = new Treecle(....some custom settings);
treecle.transform(...); // uses custom settings
Can you explain a little more on tree shaking?
Authors import individual functions, and when they create a bundle, the bundle only creates the parts of treecle they are actually using. If all functions hang on a class, then it's a monolith: either you import the whole class or none of it.
What we did in Color.js is we define each function in its own module, and it can be used independently, then we also define a Color
class that transforms these functions into instance methods.
Ah makes sense, can we just use the same hybrid approach?
Ah makes sense, can we just use the same hybrid approach?
Sure. In fact, I think it would actually be more convenient to do 3 + 1, and then people could even use custom configs and tree-shaking.
Doing 3 seems pretty annoying to have to check the context in every function; what if we went with the same approach as color.js for now and expand to adding option 3 if sufficient use cases require it?
We'd have to do something to get the config. We can't just use this.config
in the individual functions, and we can't use config
either. Color.js does not really have this problem.
It could be as simple as
let config = this?.config ?? defaultConfig;
We could even specify these as direct properties of the class, in which case it would be:
let config = this ?? defaultConfig;
We'd have to do something to get the config. We can't just use
this.config
in the individual functions, and we can't useconfig
either. Color.js does not really have this problem.It could be as simple as
let config = this?.config ?? defaultConfig;
We could even specify these as direct properties of the class, in which case it would be:
let config = this ?? defaultConfig;
Yeah sorry I think I misspoke, I think having something like let config = this ?? defaultConfig;
is not a big deal, I was referring to it being annoying to have to have context
as an argument of every single function
Closed via https://github.com/mavoweb/treecle/commit/b9deb2f594695604ebea19c000095a1ef4c0359b (forgot to mention this issue)
Currently, which properties are child properties and what values are nodes are functions that live in
src/config.js
. The workflow being that authors would import that and override its properties.The issue with this workflow is that currently you can only have one configuration. Given how generic Treecle is, it makes sense to allow different configurations to co-exist.
There are several solutions to this, each with its own pros and cons:
Treecle
class. This is the most obvious option for facilitating different configurations, however it will be a pain to facilitate tree-shaking with it (we'd need to support both the separate functions and the class, and write the function code in such a way that it works for both (e.g.let myConfig = this.config ?? config
).config
argument or option to functions that allows overriding the global config (either entirely or for specific properties). The downside is inconsistency, since functions have different signatures and we cannot have this in the same place for every single one.config
property as the context of a function to provide a custom config. I.e.This allows us to essentially accept it as an argument without it affecting the function signatures. And bonus, if we decide to do 1, the code is already there. The downside is verbosity (4 extra characters per call) and …weirdness.