Open koskinpark opened 1 year ago
I also would like to add my 50 cents to the previous message.
So if we speaking today - from my point of view fully independent components are just impossible in drupal today.
I understand approach of Ivan, it's cool actually. It means that.. probably Ivan will be able with his approach just to copy/paste his components from drupal project to another drupal project with no extra code at all. Or even more - he can copy component and put it in some other framework (vue react wordpress - any actually). Because component contains everything inside already.
It's a simple twig for render, css and js (mostly). And some yml configuration file of component with explanation about what component is.
So maybe an option will be to split kaizen on two "kaizens". One kaizen is a drupal theme, built with drupal core standards (more or less, of course).
And another kaizen with fully independed components (which can be used where? Probably somewhere)
// regular drupal script
(function (LIBRARYNAME, Drupal) {
Drupal.behaviors.behaviorName = {
attach() {
// ....
},
};
})(LIBRARYNAME, Drupal);
It expects LIBRARYNAME
from window scope what is lottery. It may:
// script type=module
import LIBRARYNAME from"./vendor.LIBRARYNAME.esm.js";
(function (LIBRARYNAME, Drupal) {
Drupal.behaviors.behaviorName = {
attach() {
// ....
},
};
})(LIBRARYNAME, Drupal);
Component receive exact dependency. More details in this PR and in this blog article
More details about js modules
No restictions to use them on any project of current drupal browserlist:
In case of Drupal provided library we have no option to generate required bundle.
You cannot do it in Drupal.
// More detailes: https://glidejs.com/docs/setup/#using-es-modules
import Glide, { Controls, Breakpoints } from '@glidejs/glide/dist/glide.modular.esm'
And receive only Glide, Controls and Breakpoints. In Drupal you always will import ALL library bundle.
In this PR for example Slider has 59Kb. (22Kb minified, also vite has gzip from box) instead of 97Kb default Glide build.
So when any of these ^ (or others) concept will applied it will be real Drupal way.
5. Components will be ready out of the box even after simple copypaste and not require local or CI build actions for usage. Only for local modifications.
When you moving components between projects with different design system applied, like: a) Other media breakpoints b) Other css variables system c) Other build process d) Something else
You need to adapt to the new system, instead of just copying / pasting your component into the new theme and that's it. Two examples:
a) Your component have the following css: padding: var(--space-2);
-> which returns 10px. In new design system --space-2
variable returns 20px. Which means after copying your component into new design system you anyway have to edit it to follow new design system.
b) What's most important to me are media breakpoints. It's different per project. Which means if in your component you have the reference to the "my-xl-super-custom-breakpoint", but on new project you don't have such breakpoint -> again! You have to edit your component.
Maybe i could write more examples, but still. Components will be ready out of the box even after simple copypaste
- it's not true, because it will not be ready out of the box.
=====
7. Frontender may have minimal knowledge of Drupal for creating component system
It's ok until you building only simple components like buttons, text fields, checkboxes. But when you need to build "always-unclear-stuff-for-frontender" like cart block (provided by commerce module), or more common example - Menu. Menu is not simple component. You have to learn drupal first before doing menu component. And of course there can be lots of other drupal specific components, not related at all to the BEM, Atomic design, or something else -> totally related to Drupal and you just can't do anything with it, and you will not be able to apply "abstract" component for it.
=====
8. Only few (1-5) of components in current regular projects have external dependency.
It's true and not true. There is always projects with a lot of external dependencies. What's most important to me is that with modular javascript drupal can't aggregate those files.
So with the following library declaration:
- o-slider:
js:
assets/vendor.glide.modular.esm.js: { attributes: { type: module } }
assets/o-slider.js: { attributes: { type: module } }
Drupal will never aggregate & minify these. This is what drupal returns on DOM with aggregation enabled:
<script src="/path/to/your/modular/asset" type="module"></script>
Once again - i could agree that it's not a problem if you use 1-5 dependencies to modular assets. But as a said - it's not true. Because you can have a lot of dependencies on some projects. And if they will be all modular, it's bad.
I can answer to your next question @iberdinsky-skilld right now: theme shouldn't do drupal's job -> which means we don't need to compress & minify modular assets by theme's build -> it should be on Drupal's shoulders.
=====
Why it is bad to use browser Window? Let's ask expert.
If to read ChatGPT answer fully - you will see the two options it suggests:
I already answered above why module javascript is bad, now i would like to touch second option we have (an option drupal core follow):
((Drupal, once) => {
Dependency on once
library.
(($, Drupal, once) => {
Again once
and jquery
})(jQuery, window, Drupal, drupalSettings, window.tabbable);
If you are not sure your dependency will exist or not, just write
if (!window.something) {
return;
}
So about namespace - check webform module (a nice example illustrating unique namespaces). For us - we can use something like:
window.themeNameLibraries = {
library1: {},
library2: {},
library3: {},
}
Such namespace will never have collisions.
If library is huge, like slider, you still can do this:
import Glide, { Controls, Breakpoints } from '@glidejs/glide'
window.themeNameLibraries.library.Glide = Glide;
window.themeNameLibraries.library.Controls = Controls;
window.themeNameLibraries.library.Breakpoints = Breakpoints;
So in the compiled version of this javascript file you will get only necessary methods or properties in window. And your resulting file weight will be not 60kb, but 20 or 30 (which is good).
This is where we are, this is standards of today's drupal core. And it's good standards from my point of view, so it's not worsens or slows down frontend development. And it's pretty clear approach even for non-drupal developers.
Once again, drupal's approach is next:
By the way @iberdinsky-skilld i have a question for you. If component can be fully independent, then what to do with such simple situation?
Where to store icons? In both components? If your answer is "no, icons can be centralized in one place" -> that means your components already can not be fully independent. So when you will copy your component and put it in new theme on another project - you also have to take care about:
So moving components between projects with no extra code - it's just a dream. It only will work on the "equal" themes, which is never a case for us.
I'm sure we need to keep approch compatible with core, which is going SDC way. It will help onboarding and support cheaper
Ref https://www.lullabot.com/articles/getting-single-directory-components-drupal-core
Hello everyone. I don't want to repeat all the points which (i agree with) @koskinpark has been providing during this discussion here and in #stack.drupal and want just share my thoughts - as we are talking about Drupal (in general meaning, Drupal theme meaning, etc.) we should take into account next things:
kaizen
and then add needed optimisation, do changes, create/make independent components which can/should be independent, add global variables if needed so, etc.I can discuss technical things but there've been a lot of technical points which we still trying to consider so i think my thought is clear and understandable without technical details. Please let me know if you have something to ask.
Hello.
While we're working with Drupal, we should take it into account.
In this PR i created 5 slider components with both approaches and more:
Using current build system with yarn workspaces(which gives us extra features like dependency install). Build speed not critical on proof-of-concept step. Later it can be optimised with parallel yarn etc. From my point of view it is better to keep all options on board because of reasons explained later in this comment.
In traditional Drupal way core, modules and themes declare their libraries and dependencies. Now we meet situation when some new entities(SDC, patterns) may declare libraries aswell.
And if we define Drupal way as the way of stability should components control their dependencies in their own code?
They are not third-party libraries but personalised bundles. Smaller size. Smart optimisations. Strict dependency.
From documentation and recent changelog and some future plans we may see that this is not restricted by Drupal. And probably will adapted one day. More than this we have much more optimisations possible with vite/webpack because they are developed to manage javascript assets.
Yes. But mostly theme related. I checked few recent projects and didn't found projects where we had more than ~3 components(not helpers or whatever!) with external dependencies. They are mostly slider, selectbox maybe tabs and menu. If anyone knows more please extend this list with them.
First approach assumes global css variables using failback values
.a-button {
--a-button-padding: var(--space-value-from-theme, 10px);
padding: var(--a-button-padding);
}
If we copypaste generated css it will contain code like:
@media (min-width: 1024px) {
.a-button {
...
}
}
So no problem will be with breakpoints OOB.
"my-xl-super-custom-breakpoint"
looks some fantastic value. Plan is to unify breakpoints somehow. Especially for shared components.
True. Evil designers never paint same design for all websites :)
But ready OOB
for component with dependencies means that it is ready in terms of functional. Not in terms of design. Slider will slide. Selectbox will selectbox(or selectboxing).
We need build process to copypaste? Also build process planned to be same.
Cart block(same as all commerce theming) is obviously out of scope of this improvement (covering 80% of components implementation work). Simpe menu is panned be in default components list after setup.
If we generate bundle for simple slider like:
import Glide, { Controls, Breakpoints } from '@glidejs/glide'
window.themeNameLibraries.library.Glide = Glide;
window.themeNameLibraries.library.Controls = Controls;
window.themeNameLibraries.library.Breakpoints = Breakpoints;
Few questions appear:
It will just return broken component until developer will not add this dependency on !different(theme) level in second approach. (remember decentralised companies and level of developers facts ^).
In first approach we guarantee that component will always work because of:
Holy true. But if we talk about 20Kb in 2023 of page loading(which is better to be tested before declared, maybe first approach will be faster who knows) it doesn't have sence if we compare with development processes optimisation and obvious stability.
global assets disqussion moved to own ticket. I didn't work on it.
@iberdinsky-skilld maybe breakpoints could be passed as css-vars?
@andypost they are passed as css vars. but it is possible in postcss only, we use https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media with variables based on theme.breakpoints.yml as usual ;)
As you know - we are reworking kaizen. And we have two big subjects regarding this:
In this issue i would like to touch a little bit first subject in terms of component's approaches. And i would like to hear your opinions.
Basically we have two approaches available now regarding all this:
Approach proposed by @iberdinsky-skilld - as much as possible independed components. No relation (or almost no relation) between components. Component have everything it need inside of it. a) css variables b) third party libraries lives inside of component c) no include or extend in twig templates. d) all images, icons affected by component - lives inside of component
Approach proposed by me - slightly independent components and more drupal way a) global css variables stored outside of components (same as we had in kaizen all these years). b) third party libraries lives outside of components (collected in one place. Each library have own drupal library declaration. Can be connected to component as a dependency). c) Possible includes or extends in twig (with relation to other components) d) For the icons - still global svg sprite, stored outside of components.
The thing is - both approaches are technically different and not only that. And it's impossible to have both approaches integrated in theme at the same time, so:
Please share your thoughts regarding this. Thanks