weixin_39586649
weixin_39586649
2021-01-11 21:40

an idea for core

hey and everyone in /owners and other people watching, would love some feedback on this...

i'm super excited to see some so much activity from jon on component (and component.io and docs!) and seems like we're getting close to 1.0.0 which is sick

i wanted to get this kind of discussion going while 1.0.0 is still not finalized before its too late to make changes like this

i've just pushed up a branch called idea which you can check out. i had some ideas for how we might potentially be able to structure the core library while refactoring around a component-oriented, and functional approach. this is still in the early stages of the idea, but please check out that branch and let me know your thoughts.

specifically check out: - the Component constructor as the core API that users interact with - the install logic - the component-install logic

a couple caveats: - i deleted a bunch of the code, not because i think those things shouldnt be in core, but just so i could get a sense for what i had successfully reproduced and what i hadn't yet. aka just so i could concentrate, so don't worry if you're thinking "where's component search?" or similar - i built the installer with a simpler way to resolve semver. to reduce complexity and since CSS doesn't have a good way to version itself, i went with the ruby/python/whatever approach where if there are conflicts, the whole thing fails. i think with CSS not having a way for us to version things this is a logical way to approach the first attempt, since it also means we get to drastically cut the complexity of having to manage multiple builds for a given component - this is still a work in progress, lots of features from spec and such aren't implemented. that isn't a decision not to implement most of them. there are a few however (like globbing) that i've eliminated from the current prototype on purpose to reduce complexity, and they could potentially be added in later, but for now i saw good simplicity gains from keeping them out on purpose - some of the async-ness of install can still be simplified, doing that as i go along. of course some of the install code is just complex because the process is complex by nature - build is still very much a work in progress, seeing as it doesn't do anything :) starting into that right now - i haven't added in locals support yet at all, but will soon. that will surely break some of the abstractions and require rethinking some - some of the logic like remote would be in a separate repo. i signified this by anything that is in a folder inside of ./lib, so that means we'd have component/logger component/spec etc.

what i was looking to do was try to reduce complexity wherever possible, sometimes that means cutting features, or just nice-to-haves, so that we can arrive at a solid core to build on top of. there still needs to be more refactoring

i would love input on what you all think, if this is a valid-looking direction. and if anyone wants to hack away with me i'm going to pursue the idea some more over the next two days

该提问来源于开源项目:componentjs/component

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

41条回答

  • weixin_39575758 weixin_39575758 4月前

    For the repo with many files like https://github.com/chaijs/chai, why can't they build a single file and add that file to component.json? Doesn't seems too much work, comparing the downloading process is quite terrible for so many single files, and I have no idea when the SPDY would be available for github CDN.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    haha luckily its a call for future us

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    ~~the downloader already supports tarballs and zipballs. it uses them when there's more than 10 files in a component so it doesn't do 10 HTTP requests. also need it for https://github.com/component/component/issues/483. WOOO MORE COMPLEXITY!!!~~

    oh nvm you mean tarballs as dependencies. i don't know why people do that.

    点赞 评论 复制链接分享
  • weixin_39995764 weixin_39995764 4月前

    oh interesting, so you're already downloading the full tarball in some cases?

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    yeah. when testing chaijs/chai, that shit took like 5s alone to install because of all the HTTP requests.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    wouldnt it take just as long as it did in component.x since its just raw.github access? or was there a change that makes it takes much longer?

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    i currently install 5 components concurrently, and each installs 1 file at a time. it's just stupid concurrency stuff because i was targeting 5 global, concurrent HTTP requests at any given time (which is what will happen under the hood by default anyways because of node's stupid HTTP pooling. ).

    you could always bump up the concurrency, but i think i need to just think of a better control flow mechanism. would cleanup a lot of code. going to open an issue for that.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    just checked on this branch, downloading all of the files for chaijs/chai is like 1 second

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    yeah it's just a concurrency control option. i can bump it up to higher, i just don't want to deal with HTTP pooling issues, specifically when you're installing an entire app, not just a single component.

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    hopefully we can get rid of all of this stupid concurrent HTTP crap once a CDN supports SPDY or node gets their hsit together

    点赞 评论 复制链接分享
  • weixin_39824898 weixin_39824898 4月前

    hmm is the http pool issue the same one that substack's hyperquest addresses? not sure what he's doing to get around it but might be something to look into

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    yeah. there are multiple ways around it, but they all have tradeoffs. my approach is just to keep it close to 5 concurrent HTTP requests. i also don't know how proxies and such would handle it. not something i want to fiddle with since we could just wait until SPDY and ignore it.

    点赞 评论 复制链接分享
  • weixin_39805883 weixin_39805883 4月前

    Couple of thoughts after reading all of this: - The idea of throwing at mismatch is the safest option I think, but this could be run with a build/install flag instead. I'd rather make sure I have a build that is guaranteed to work. Having CSS just override each other silently just isn't a viable option. Maybe we could add a bit of complexity and only throw an error if there is a mismatch in a component with CSS. - Splitting everything in a ton of different repos can seem nice, but we don't want to go overboard with it. Keeping things together is sometimes cleaner than the maintenance overhead. There's no reason the CLI tool and component.js can't be together, right? - I personally don't think there should be a strong focus on install speed. Slow builds suck, but mysteriously broken builds and lack of semver suck more. Sure, you save a few seconds, but we still don't have semver, so lets just get something working and improve from there. - In the wild CSS conflicts don't happen that often. I can't remember the last time I'd had an issue with it even though each new version just blasts the previous one. There are only a few cases where you'll be using someone else's CSS since it is something that is really unique to your own app. There are utility libraries like suitcss but even they won't change that often and can be pegged as root dependencies. There are things like structural styles in UI components that could break, but even they don't actually change that much across versions. - Globbing just isn't needed most of the time. If someone is building a big app it will be internal and they can just use something like component-assets to fill out the manifest. You could even add that to your Makefile before build and you'd never have to worry about it.

    What's the goal with this branch? Semver? Or just code quality/organization? There have been a lot of sweeping changes to Component for 1.0. That has had me a bit worried tbh.

    I think we're trying to make too many changes at once here. It's going to be unmanageable and unreleasable. We should pull back and make smaller, incremental changes.

    Maybe there is some other way we could handle CSS that we haven't thought of yet as well. I think we're screwed until we get real web components. Hell, just drop support for CSS in remote components and it wouldn't be a problem ;)

    点赞 评论 复制链接分享
  • weixin_39995764 weixin_39995764 4月前

    Great list. I was thinking about this a bit last night too and i think the CSS issue just has to be handled differently. It's seems to me that:

    Javascript is more likely to work when you have proper versioning, but CSS is less likely to work.

    I like 's suggestion about having a warning (or even error out) when there is a CSS version mismatch.

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    we can warn on mismatches automatically. right now i tried to avoid warnings everywhere because they get really annoying and the user can't always do something about it. don't want this turning into npm. maybe warn only on semver conflicts by default.

    but erroring out is not doable IMO since dependencies will sometimes pin their stuff and then you'd have to fork it just to even get a build, which is a pain in the ass.

    There have been a lot of sweeping changes to Component for 1.0. That has had me a bit worried tbh.

    what do you mean? aside from some people not being able to hit the remotes, Component v1 is pretty set so far

    点赞 评论 复制链接分享
  • weixin_39668479 weixin_39668479 4月前

    I think we're trying to make too many changes at once here. It's going to be unmanageable and unreleasable. We should pull back and make smaller, incremental changes.

    I think reducing core is a noble goal but maybe there could be a promotion strategy, where, as things becomes demonstrably stable, they can be merged into component/component (in support of making smaller incremental changes)

    As far as remotes go it would probably be overkill for now but if we maybe started supporting the whole { "bitbucket.com/foo/bar": "1.x" } sort of syntax similar to Go, and repo/user would just imply the github support that we already have. Not sure if that's worth tackling for now since long-term it would probably just end up being parsed from the import statements.

    I think this would be a good idea at least for reducing requests made, decreasing install time. I cringe a little bit though because I remember Go package management being a nightmare early on to the point where the Google group about golang pm felt a bit like an emotional more than technical support group

    点赞 评论 复制链接分享
  • weixin_39949584 weixin_39949584 4月前

    I'm working on an app that has a lot of proprietary stuff scattered into libs. I'm currently maintaining a component.json:scripts array around 20 items big - adding/removing files as I work on it.

    Needles to say, this process is extremely annoying. gave me hope on irc when he showed me the new globs he was working on, and I almost fainted by thinking that the whole array could be replaced by a single lib/*.js glob. I beg you on my knees, don't take it away :'(

    点赞 评论 复制链接分享
  • weixin_39824898 weixin_39824898 4月前

    not sure I agree, we used to do it that way and making everything into self contained components simplified everything: explicitly tracking component dependencies is a major one. A lot of the labor is removed once you have an automated way of creating local components.

    but then again that's just our way of doing things, and who am I to tell everyone how to structure their project. So I have no problem conceding this point.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    i agree with on this. it's all about just automating the initial creation (and i dont even do that yet) but then the upkeep on existing components is practically null if they are self-contained from the start

    that being said, i think globbing could (?) be added back in here unless im missing something core to the way it works, so i'd rather leave that for a "next" part of the discussion and instead discuss the core way this idea is laid out differently

    i think (?) that may be solved in this installer already. i chose to fail out when it first finds a semver mismatch, and it just recurses through the tree, but only ever do a single level at once. there's a non-low chance i might be missing something obvious though :)

    点赞 评论 复制链接分享
  • weixin_39927861 weixin_39927861 4月前

    About the globbing. I'm not against it. I kinda feel tempted.

    But it could be avoided by providing some sort of component-add or component-remove commands, or anything to help construct the component.json file in cases where there is an assets directory full of images and fonts and all kinds of required stuff for major apps.

    It could make developers life easy and keep out the complexity of the component core.

    My two cents.

    点赞 评论 复制链接分享
  • weixin_39788740 weixin_39788740 4月前

    I sort of agree in general that it's annoying to have component.json's in the modules, however if you don't then your app is basically just one monolithic thing with root dependencies, which is both good and bad I suppose. I guess that's where globbing really comes in at the app level if you want to do a less modular application with the deps in the root component.json only. At the public component level it's pretty rare to have a lot of files.

    The way I see it generally is that it's akin to having many modules for your app in npm, like we have 500+ now, it's annoying but at the same time it's the "right" thing to do, but I totally agree it's super annoying at the prototyping stage.

    I like the idea of having the lib-ish stuff out of component/component to keep it more focused on executables. Structurally I like the functional approach, if we exported them we could unit test them pretty good, testing the whole thing end-to-end with lots of filesystem state is pretty awkward haha, I sort of gave up with that in the builder it's too weird.

    As far as remotes go it would probably be overkill for now but if we maybe started supporting the whole { "bitbucket.com/foo/bar": "1.x" } sort of syntax similar to Go, and repo/user would just imply the github support that we already have. Not sure if that's worth tackling for now since long-term it would probably just end up being parsed from the import statements.

    点赞 评论 复制链接分享
  • weixin_39788740 weixin_39788740 4月前

    I guess the main bad thing about throwing with version conflicts is that if someone else owns the repo you might be waiting on them to make changes (though you could fork), but that could get a little weird but definitely true that css-wise you're fucked at that point anyway

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    we have to support multiple versions now because a lot of components currently pin their deps due to component's lack of versioning support =/

    点赞 评论 复制链接分享
  • weixin_39995764 weixin_39995764 4月前

    i think multiple versions is definitely a good idea during prototyping. correctness is more important than bundle size in the beginning. then you can use tools / fork repos to optimize your dependency graph later.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    not that many pin their deps though. most of mine i left unpinned (and all of ours internalled are unpinned) since keeping up with the version changes wasn't worth it. going through the component org while testing i had to work to actually find conflicts that would let be easily test logger.fatal haha

    for multiple versions how were you thinking CSS would be handled? i can't find a good solution for it, so i think multiple versions is out unforunately. otherwise we're going to end up with tons of dev time spent not realizing why CSS is messed up. i think it's much clearer to the user whats going on if we just throw like most package managers do

    点赞 评论 复制链接分享
  • weixin_39995764 weixin_39995764 4月前

    yah, but throwing won't get your app off the ground in the initial stages. you'll end up forking everything. i actually don't really understand how component is working well for people right now, it simply picks whatever dependency version comes first in the install process. at cloudup we did have this sort of strict versioning in place, but i think mandating it from the beginning is the wrong call.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    i dig that Go approach, whether we do it or not haha. you prefer the github.com approach to github://? i dont have an opinion there. i'll update the remote.name to be github.com in that case

    as for lib-ish stuff, we could make two repos component and component.js if we want to solve that part. that way we end up with a small number of repos to wrap people's head around, but we can still get the separation for the CLI niceness? i don't have a strong opinion on whether the lib should be in the same repo as the cli or not. for things like metalsmith its nice.. thats my only thought

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    i thinkw e discussed this in component/spec. the consensus was to not treat CSS any differently than JS. that's why i've added the component duplicates command to help avoid this problem.

    but i'd rather have a bad build or less-than-ideal build than no build or an incorrect build.

    点赞 评论 复制链接分享
  • weixin_39995764 weixin_39995764 4月前

    yah, multiple versions of css is definitely tricky though. i think in that case you would have to fork the repo if you didn't own it.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    i'm not convinced the strict versioning will occur in the wild that much. if you think about it, right now we have no ability to apply semver ranges and the conflicts do happen, but they are rare. when you're prototyping couldn't you just use * to make your life easier in that respect?

    with everything pegged to ~ or ^ by default the conflicts will be still be rare i think, and in that case they would be completely merited because CSS is never going to work across breaking major changes anyways, so the developer is going to get screwed with debugging the problem

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    that's why i'm thinking we should rather go with a solution that works the same in all cases, since it will make the mental model a lot easier for the user. instead of cases where only sometimes conflicts will result in potentially really hard to track down CSS bugs

    not sure which side of the ease spectrum web components would fall into

    点赞 评论 复制链接分享
  • weixin_39788740 weixin_39788740 4月前

    github:foo/bar == foo/bar would probably be the nicest, no point having the whole url I guess, unless we're going to support tarballs etc those would need to be urls anyway, dunno tough call

    点赞 评论 复制链接分享
  • weixin_39926749 weixin_39926749 4月前

    Looks neat -- Interesting !

    点赞 评论 复制链接分享
  • weixin_39715652 weixin_39715652 4月前

    +1 would be glad to have a smaller core, will look at it soon

    点赞 评论 复制链接分享
  • weixin_39824898 weixin_39824898 4月前

    Not sure I understand this, it seems to add more to the core by undoing all the work has done by splitting everything out into separate modules.

    The component object with events seems like a good idea though. The code looks clean though so can't complain about that. I've also not looked enough into 's modules to judge their complexity either.

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    My main issue is that it removes race condition checking, which is what most of the complexity in the resolver is. I still has some issues with it, which is why it currently only resiolves 1 semver at a time.

    Unglobbing is important for the future because listing more than a few files in a component.json is unwieldy. The builder would be much simpler without it. I also don't want plugins to have to implement control flow.

    I do want better logging and stuff though, but that's something that can be changed without breaking backwards compatibility.

    点赞 评论 复制链接分享
  • weixin_39586649 weixin_39586649 4月前

    totally agree about logging. can you elaborate on the race conditions in semver? didn't realize i was missing something there, let me know and i can think about how to handle that as well

    i'm not yet sold on the globbing because from everything i've worked on that's just never been a problem, as components tend to be very small in scope thanks to how easy the ecosystem is. would be keen to hear others's thoughts on that. i've been -1 on globbing for a while for that reason, since it adds complexity

    点赞 评论 复制链接分享
  • weixin_39824898 weixin_39824898 4月前

    I agree with about globbing, best reason to exclude globbing is to deincentivize large components. I can't say I've ever needed to glob anything, even at the app level. Considering most of the time its just easier to build apps out of local and remote components, and those usually just export one or two files.

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    just stuff like https://github.com/chaijs/chai/blob/master/component.json. big components are inevitable though less than ideal, but creating manifest files like that would be a pain in the ass.

    i know someone on irc complained about how manually listing all the files in every component was annoying. honestly, i think component.jsons everywhere are really annoying, but i think it's the best we can do.

    点赞 评论 复制链接分享
  • weixin_39995764 weixin_39995764 4月前

    yah, i tend to agree with . component.json's in all the local directories of an app is a lot of extra labor for quite little gain.

    if you want to open source the local component, it's really simple to add a quick component.json and release.

    点赞 评论 复制链接分享
  • weixin_39646970 weixin_39646970 4月前

    i don't even know how to explain it. semver deps have pinned deps who have semver deps, all of which use different semver. two different locals have the same dependency but different semver. you don't want to use an API request on every single semver. a lot of weird edge cases. the main issue is when you try to resolve them at the same time. you want to return the same resolved dependency, not multiple copies of it.

    right now, semver can handle like 3 resolutiosn concurrently, but i hit a case where it fails and i haven't yet figured out why. just put it down to 1 until i put time into checking.

    点赞 评论 复制链接分享

相关推荐