Skip to content
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

Where should React components be located and how should they be packaged/released? #1471

Closed
bryceosterhaus opened this issue Jan 23, 2019 · 10 comments
Labels
type: discussion Issues that are open for discussion of some change or to gather information

Comments

@bryceosterhaus
Copy link
Member

@jbalsas and I were chatting and we were trying to think about how to structure and package/release future react components. As we start to adopt more react components, we will have to re-write existing clay components and then also add new ones entirely. The question now is, where do they go and how do we release them?

Proposal 1

@jbalsas brought up the idea of adding a jsx or react folder for each existing module, meaning we would consume those components like import {ClayIcon} from clay-icon/src/react/ClayIcon. Each existing package would essentially have two flavors, the existing metal version and then an additional react version. The APIs would be independent and non-reliant on one another, and they would be able to be released under the existing package names(clay-icon, clay-drop-down, etc.).

Proposal 2

I am proposing that we release the react versions entirely separate of the current modules. Meaning we would either create a single library like clay-react that is comprised of the components or just release individual components like clay-icon-react.

My thought is if we try to re-use the existing packages, meaning we have multiple flavors of the package(metal and react), it will get messy with versioning and releasing. A breaking change for one flavor may not be a breaking change for the other. I also think if I was an existing developer using a metal component, it would be strange to see a new version of the same named module written with an entirely different framework. By releasing in new packages, the direction and goal of the package is much clearer, meaning, clay-drop-down-react is a react component that has drop down functionality and is styled like Clay.

Ideally I think if I was just a consumer of clay components for a react app, I would want to do something like import {ClayButton} from 'clay-react';.

I am curious to hear other thoughts and see if anyone else has any other ideas or strong opinions on the proposals above.

@matuzalemsteles
Copy link
Member

I do not really like the idea of ​​mixing React and Metal components in the same repository, I think this creates confusion and infrastructure problems for example.

We must think if we will continue to evolve the components in Metal in the future... I see that we are migrating to React and discontinuing the components in Metal but keeping until the teams no longer use. If we follow this line of thought we should draw a clear plan of discontinuation and when we will stop to evolve and maintain.

Proposal

Work with Branch

I like the idea of ​​keeping components separate, so we'll be free to grow the infrastructure if necessary. Keep the Metal components in a branch:

  • master-2.x - Stable Branch of Metal Components
  • dev-2.x - Metal components development branch, ready for release

The idea of ​​separating in branch we helps to create the necessary testing infrastructure for React, such as the use of the enzyme. As we're going with React Hooks I think we can start having logics on files that are more shareable among components that are not exposed to the audience, such as a layer that we can "break" without "worrying" and that will give us freedom and flexibility to this... I think of it as the shared folder that React uses internally.

Keep the React components in a branch:

  • master - Stable Branch of React Components
  • dev - React component development branch, ready for release

Releases

I think it's not necessary to change the nomenclature for the new components to symbolize that they are in React, using semver and the NPM scopes, we can make it clear that we had changes.

Metal Components

We can continue to publish the components in Metal over the current nomenclatures clay-* above the version 2.x.

React Components

We can follow a new naming pattern using NPM scopes to strengthen this change. Making releases above version v3.x.

Something like that:

  • @clay/button
  • @clay/select
  • @clay/icon
  • @clay/dropdown

Scope Clay is already being used, but it does not prevent us from using another...

Deprecation warnings

I'm not 100% sure about this and how we're going to date the warnings, but I like the idea of ​​following a schedule on component maintenance in Metal and I do not want to impose dates because they're pretty hard to think about once we deliver this to Liferay and we should take Liferay support into consideration. I also do not want to impose names on warnings, I think we can opt for softer name choices, deprecation is a bit strong. 🙂

  • Deprecation warnings - This may symbolize that we are introducing Clay v3 with React but that we are still giving support to Metal components and that they will become legacy in the future.
  • Insecure warnings - It symbolizes that we are still keeping the components in Metal but that we are warning that they are insecure and that we are not evolving.
  • Legacy warnings - It symbolizes that we are finalizing the discontinuation and that we are no longer evolving but only keeping security updates if necessary.

I like to think about this, that we are warning developers that they should worry about it but that they do not need to run to migrate, I think it's important not to let the developers feel at ease, otherwise we will never remove the components of Metal from the next releases Liferay for example.

@matuzalemsteles matuzalemsteles added the type: discussion Issues that are open for discussion of some change or to gather information label Jan 24, 2019
@jbalsas
Copy link
Contributor

jbalsas commented Jan 24, 2019

Hey everyone, thanks @bryceosterhaus for getting this ball rolling and @matuzalemsteles for already sharing your thoughts!

I'd just want to add some history and concerns that I'd like to factor in before we make any decision.

Maintenance costs

I know this might seem silly but I think it's key for us to be able to efficiently maintain and evolve this. Over the years we've started many many repos, created many more packages and abandoned quite a few of them. I'd like to avoid adding additional ones.

Every new repo comes with new decisions, new maintenance concerns, new documentation and publication needs. While an evergreen repo always seems desirable to get started, few months down the line, the added complexity usually starts taking its toll. Things become harder to explain, harder to keep somehow in sync and on-boarding new members or accepting new contributions becomes more and more complicated.

Release mode

In this scenario, I think we've already tried it all. Single component library like AUI, multiple independent components with a wrapper offering like metal-components and multiple independent components like Clay.

Both first 2 approaches suffer from the You wanted a banana but you got a gorilla holding the banana (and the whole jungle) approach. Granted, with today's build processes, some of this can be alleviated on build time, but the 🦍already made it to your machine.

Messaging and long-term vision

I'd say we're not particularly known for staying put and stable for as long as we should. I'd really want us to use this opportunity to try to follow a less disruptive path than we've done in the past.

Long term, we'd like to position Clay as a Component Library. This means:

  • Simple css and html components that anyone could easily put together in a web page or in their own developments to create components.
  • A rich set of React components, ready to be used and highly customizable and composable
  • Some interop layer on top (WebComponents) so developers could use Clay regardless of their technology of choice

One thing that has bitten us in the past has been tying developments to technology. That's one of the things we were trying to avoid with Clay, and that's the reason why we didn't end up calling this metal-components or clay-metal-components. As a long term solution and one that we (or our Support colleagues) will need to support for a long time, I'd like to keep our different offerings as close together as possible.

My 2cts

I really like @matuzalemsteles idea and I would personally root for that one.

  • Branch off master and develop to 2.x and develop-2.x branches
  • Make master and develop our current ones to hold only react components (plus WC wrappers)
  • Keep the library site and docs in sync within this repo :)

@wincent
Copy link
Contributor

wincent commented Jan 24, 2019

I am proposing that we release the react versions entirely separate of the current modules. Meaning we would either create a single library like clay-react that is comprised of the components or just release individual components like clay-icon-react.

This would certainly keep things well isolated, but it is a bit of leaky abstraction. In 2023 will we need to release clay-new-hotness (or clay-icon-new-hotness?). I think there's some value in keeping the package names focused on the Clay "brand" without tying them to their implementations.

We can follow a new naming pattern using NPM scopes to strengthen this change.

+1 to the idea of scoped packages. I was going to suggest it too, but was a bit sad to see clay is already in use. This brings us to one of the 2 hard problems (@clayui?). Scoping gives us the option of increase the package count indefinitely over time without ever having to worry about name-squatting or people getting confused about what is "official" and what is a third-party module. Independently of any move towards React, adopting scoped packages would be a good idea.

I think it's not necessary to change the nomenclature for the new components to symbolize that they are in React, using semver and the NPM scopes, we can make it clear that we had changes.

A major semver update is often something as simple as "foo() now requires an additional third parameter", "or "bar() has been removed in favor of betterBar()", so having something dramatically different is still going to be a bit of a shock. I think semver-major + moving-to-scopes would definitely help with that.

Over the years we've started many many repos, created many more packages and abandoned quite a few of them. I'd like to avoid adding additional ones.

This is a great point. One of the benefits of the monorepo approach is that you have a single place to sort through all the problems, even if the task is made more complicated by having two kinds of components to deal with. You need something conceptually sound to tie it all together though in a coherent fashion, and we definitely have that here (Clay as an implementation of Lexicon).

I really like @matuzalemsteles idea and I would personally root for that one.

We should make the decision on how to structure repos/branches based on the time frame that we expect to be maintaining both Metal and React versions of the components. That is to say, if we wanted to keep them in sync indefinitely in terms of functionality/appearance etc, that would probably lead to a very different structure than if we wanted to transition off Metal as fast as possible and then never touch the Metal versions of the components again. (I don't actually know what our plans are in this sense, but I get the sense that we're closer to the second than the first, right?)

One final thought about branches: it might be nice to have a visual diff tool in place that allows us to compare Metal and React versions of a component. (At least initially, they should be indentical right?) I don't know whether this would be easier to set up without branches. Or not. Food for thought anyway.

@carloslancha
Copy link
Contributor

Hi guys, you mostly said my thoughts so in resume: I agree with @matuzalemsteles branch proposal :)

@bryceosterhaus
Copy link
Member Author

Great idea, @matuzalemsteles. I really like that proposal. I hadn't thought about using NPM scopes and I think that will help differentiate v2.x and v3.x even more so. As for branching and actual code location, would we just start V3.x by removing all of the soy and metal components and then slowly add the new react components to that branch? I would think that the v3.x can essentially start from scratch but also take hints and model APIs, so long as they make sense, from v2.x. I am very bad at visualizing these things sometimes 🙃

One thing I hope we can nail down is not having to compromise on how React components are built. I think it would be wise of us to create the react components in the same manner the react community would and then secondarily create some sort of compatibility layer that would allow us to expose the components for easy consumption in portal, taglibs, or web components. If we are able to do that, I think it would be a great success!

Great feedback from everyone though! It is much appreciated.

@julien
Copy link
Contributor

julien commented Jan 25, 2019

One thing I hope we can nail down is not having to compromise on how React components are built. I think it would be wise of us to create the react components in the same manner the react community would and then secondarily create some sort of compatibility layer that would allow us to expose the components for easy consumption in portal, taglibs, or web components. If we are able to do that, I think it would be a great success!

Agreed!

That said, concerning the WebComponents "wrapper" I have my doubts: I don't want to start a debate here, but while it might seem a good idea to offer this funcionality, I personnaly don't see WebComponents moving anywhere: https://caniuse.com/#search=web%20components ...
It's a bit like ES modules: we've been hearing about them for years but no one uses them "natively", everyone transpiles to es5 and uses a bundler ... and I wonder what kind of magic we'll have to do to "make" WebComponents work consistently in the different browsers we support ... is it really worth the effort? But that's just my 2 cents.

@matuzalemsteles
Copy link
Member

hey @jbalsas, thank you for passing your insight on this, I greatly appreciate it. I fully agree with you. About the documentation, in React, I would like to go with some different information proposals on the page of each document, it would be a great opportunity to gather feedback and visualize what we need to improve there.

+1 to the idea of scoped packages. I was going to suggest it too, but was a bit sad to see clay is already in use. This brings us to one of the 2 hard problems (@clayui?). Scoping gives us the option of increase the package count indefinitely over time without ever having to worry about name-squatting or people getting confused about what is "official" and what is a third-party module. Independently of any move towards React, adopting scoped packages would be a good idea.

hey @wincent I'm really sad too when I discovered that clay was already in use, I'll try to contact the developer to find out if it gives us the name 🙂.

I really like that proposal. I hadn't thought about using NPM scopes and I think that will help differentiate v2.x and v3.x even more so. As for branching and actual code location, would we just start V3.x by removing all of the soy and metal components and then slowly add the new react components to that branch? I would think that the v3.x can essentially start from scratch but also take hints and model APIs, so long as they make sense, from v2.x. I am very bad at visualizing these things sometimes 🙃

hey @bryceosterhaus I think this is the best way, we can start structuring from scratch, following the structure of v2.x.

I would start by configuring the yarn workspace with lerna, structuring the necessary folders, linter... and configuring the testing infrastructure for React and would already send ClayDatePicker and ClayColorPicker there. I do not think we need to work on the current developer branch to remove all components...

That said, concerning the WebComponents "wrapper" I have my doubts: I don't want to start a debate here, but while it might seem a good idea to offer this funcionality, I personnaly don't see WebComponents moving anywhere: https://caniuse.com/#search=web%20components ...
It's a bit like ES modules: we've been hearing about them for years but no one uses them "natively", everyone transpiles to es5 and uses a bundler ... and I wonder what kind of magic we'll have to do to "make" WebComponents work consistently in the different browsers we support ... is it really worth the effort? But that's just my 2 cents.

hey @julien I also agree with you.

I'll leave just some feedback on walking with WebComponents in React: React currently offers almost no support or intent to support (See this conversation https://dev.to/ben/why-the-react-community-is-missing-the-point-about-web-components-1ic3), so yesterday I started working on Wrapper for React but I noticed some challenges that we will face to add considerable support to this.

  • It is considerably difficult to pass properties that are callbacks, we are using this to be able to make the components uncontrolled.
  • We could not update component props with new values ​​for example. (Some libraries add lifecycles to classes to update, with hooks I did not think of anything...)

I have not listed many of the difficulties we have on our side in supporting WC, but to do this we will have to create many workarounds and make it quite difficult when the React team does not think about giving support.

Some libraries who try to give support:

@bryceosterhaus
Copy link
Member Author

Since we seemed to have a general consensus, I decide to just start with a PR for the v3.x branch. I also went ahead and created the @clayui scope on npm in case we are unable to acquire @clay.

#1485
https://www.npmjs.com/org/clayui

@matuzalemsteles
Copy link
Member

Great!

Just an update on the @clay org: I contacted the NPM team, we will have to wait for 4 weeks to get a response from the author, if not we will proceed.

@wincent
Copy link
Contributor

wincent commented Jan 29, 2019

@matuzalemsteles: that's awesome.

bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
bryceosterhaus added a commit to bryceosterhaus/clay that referenced this issue Feb 1, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Feb 4, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Feb 4, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Feb 4, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Feb 4, 2019
matuzalemsteles added a commit that referenced this issue Feb 4, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Feb 5, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Feb 26, 2019
matuzalemsteles added a commit to matuzalemsteles/clay that referenced this issue Mar 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: discussion Issues that are open for discussion of some change or to gather information
Projects
None yet
Development

No branches or pull requests

6 participants