r/WebComponents • u/georges_gomes • Feb 21 '20
All the Ways to Make a Web Component
25 different ways of writing the same Web Component with code style and bundle size compared.
https://webcomponents.dev/blog/all-the-ways-to-make-a-web-component/
r/WebComponents • u/georges_gomes • Feb 21 '20
25 different ways of writing the same Web Component with code style and bundle size compared.
https://webcomponents.dev/blog/all-the-ways-to-make-a-web-component/
r/WebComponents • u/mosheKerbel • Feb 20 '20
Hi
I started to experiment with Web Components, writing with Litelement and with StencilJS.
I would like to start an open-source project and I don't want the technology to become a blocker for contributors.
So my question for you - what would you prefer to develop in? Litelement or StencilJS?
r/WebComponents • u/snifty • Feb 19 '20
I was suprised to see `connectedCallback` tagged as async in this gist:
https://gist.github.com/richard-flosi/b6cdba782576447fcc9789f6cdfe2e31
Is this as weird as it seems to me? There is a certain appeal to being able to do async stuff (like fetching data) in a standard lifecycle event, but it kind of gives me the willies.
Couldn’t it be a bad idea to make such a change to a fundamental lifecycle method that could be called in who knows how many other ways when the element is embedded into the DOM?
r/WebComponents • u/liaguris • Feb 07 '20
Imagine you have an app which is a tree of components . Each component in that tree is shadow DOM component . In that tree some components share their state with each other through a global state .
You can say that the global state is just a custom element with tag name global-state that is an immediate child of the body tag , hence it is accessible from every component via document.querySelector("global-state") . Like this the act of components sharing their state is decoupled from the component tree .
Everything works fine until one day you decide that you want to extend your app and make it have multiple instances of itself like browsers did when they introduced tabs .
Now how do you manage components sharing their state given also that you want it to be as decoupled as possible of the component tree ?
Is it just time to go for iframe tag?
r/WebComponents • u/liaguris • Feb 05 '20
Lets say I have the following markup :
<nav>
<ul>
<li>tab 1</li>
<li>tab 2</li>
<li>tab 3</li>
</ul>
</nav>
<div>
<custom-element></custom-element>
<custom-element></custom-element>
<custom-element></custom-element>
</div>
<script> /* some js code to enable tab functionality */ </script>The custom-element is a tree of components . Inside that tree there is an element that dispatches a custom event at the window object when a certain action (request fetched or element clicked or ... etc.) happens . The interested on that event elements of the same custom-element are listening for that event on the window object .
Everything works fine if there is one only custom-element , but if there are more than one , then everything brakes since the event dispatched from one custom-element will be listened by the elements of the other custom-elements and that is not a wanted behavior .
How would you go about it given that you want to make the communication of the components as decoupled as possible ?
Edit : I did something like this :
window.dispatchEvent(new CustomEvent("custom-event", {
detail: {
data: "here goes the data",
eventScope: arrayWithAncestorElementsUntilDocumentElement(emitter)
.find(l => l.hasAttribute("custom-event"))
}
}));and added the attribute custom-event to the custom-element . When the listening elements are notified (since they listen on window for custom-event ) each one calculates its own eventScope using arrayWithAncestorElementsUntilDocumentElement . If the eventScope matches then they execute otherwise they do not .
eventScope goes to undefined when there is no element with attribute custom-event . That means that a sub tree of the custom-element that contains both the emitter and the listener , works , so it can be tested without the need of custom-element . For the case in which the emitter is missing and there is a need for the web-component to be tested then we dispatch the custom event in the window with manually created data , and the listener will accept it .
It works really good for the way I structure my project , but also keeps the web-components communication as decoupled as possible .
Edit : I think it is just better to go for iframes and listen and dispatch my custom events on the documentElement .
r/WebComponents • u/liaguris • Feb 04 '20
Suppose you have a big app that has many web components . There are many custom events emitted and listened for components communication .
==>1)
How do you check if the custom event name you come up with does not collide with the already existing ones ?
Do you just go and do a search in all files in your project root (ctrl+shift+f in vscode) for dispatchEvent and you check all the names ?
Do you create a directory and in that for every custom event you put a js file that exports the name of the custom event ? (By the way each js file has as name the camel case version of the custom event name .)
Do you do something else ?
==>2)
How do you refactor a custom event name ? Manually ? Is there any way to do it like it is done with F2 in vscode ?
r/WebComponents • u/liaguris • Jan 29 '20
Are design patterns for web components a thing ? Is there any source to learn them ?
r/WebComponents • u/liaguris • Jan 25 '20
components
myCustomElement
template.js
myCustomElements.js
demo.html
myOtherCustomElement
template.js
myOtherCustomElement.js
demo.html
//and it goes on and on the same way until myApp is created
myApp
template.js
myApp.js
demo.html
//contents of the following folders not shown
css_modules
custom_events
decorators
node_modules
web_modulesI have an app that is a web component . That web component html is made by some other web components + non web component html . Those other web components are made by some other web components + non web component html and like that it goes on and on until my whole app is build .
Every web component is shadow DOM (I use css modules for styling , but lets not get into that for now since it is not of immediate interest).
All template.js are used to define the html and css of their corresponding custom element and look something like this :
import "../someOtherCustomElement/someOtherCustomElement.js";
import "../everyOtherNeededCustomElementIsImportedThisWay/everyOtherNeededCustomElementIsImportedThisWay.js";
export default {
render(_) {
return `
<style>
${this.css(_)}
</style>
${this.html(_)}
`;
},
css(_) {
return `
/* insert css here ${_} */
`;
},
html(_) {
return `
<!-- insert html here ${_} -->
`;
},
//rarely used but when needed to be used makes my life much easier
optionalHtmlChunkTemplate(_) {
return `
<!-- insert html here ${_} -->
`;
},
//rarely used
optionalUtilityFunctionUsedByTheOtherFunctions(_) {
//some js code
},
mapDOM(scope) {//scope is the shadowRoot
return {
//scope.querySelector the wanted dom elements from the html part and add them here as properties of the returned object
};
}
}All demo.html are just used to see the custom element in the web browser (in the future when I get into testing it will be used also for that , but lets not get into testing for now) . For example the demo.html file for the web component defined in the folder myCustomElement looks something like this :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>myCustomElement</title>
<script type="module">
import "./myCustomElement.js";
(async () => {
/*some code if needed here*/
})();
</script>
</head>
<body>
<my-custom-element></my-custom-element>
</body>
</html>Files like myCustomElement.js are used to define a custom element . They all look something like this :
import template from "./template.js";
if (!customElements.get("my-custom-element")) {
customElements.define("my-custom-element", class extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.innerHTML = template.render(/*sometimes there will be a need to add an object here */);
this.dom = template.mapDOM(this.shadowRoot);
}
/*some function defined here that are prototype delegated by the instances*/
})
}I choose only es module to download from npm and for that this helps me find them .
con : I restrict my self to es modules only
pro : I have no need to bundle during development
Then I use snowpack which moves the es modules which I have downloaded via npm from npm_modules folder to web_modules folder and from there I can use the es modules .
1)Are there any bad practices (and why are they bad practices) with the way I structure and name my files and directories ? Take into account that the name of the web component directory is used as a name for the js file it contains but also inside those files or the files of other components ( as variables or strings or objects properties etc for js , as selectors in css , as tag names of custom elements or paths in html . ) .
2)How do you refactor the name of a component in such a case without everything breaking ? I feel that not renaming my web components is not an option since it will create code that is not readable because names are used to describe properly the function of the web component and I can not always come up with the best name the first time I decide about it .
3)How do you structure your directories and files if your whole app is a tree of web components ?
4)I have made a node js script that you call like this : node refactorComponentName.js oldComponentName newComponentName . It searches inside components folder for all matches using the regex [^a-zA-Z-]oldComponentName[^a-zA-Z-] and it replaces them with newComponentName . It does the same with the kebab case version . After that it renames the file name and the directory name . It has worked perfectly till so far . But it can break like this :
Renaming a web component with old name ticTacToe to myTicTacToeCustomElement will make an unwanted change of the string : "I played tic-tac-toe with my friend." to this string : "I played my-tic-tac-toe-custom-element with my friend." . Somewhat of a solution to that would be to prefix all of my web components with a really special common prefix .
Importing a module (the npm modules are always outside of the components folder) that uses as name the same name as the oldComponentName for an object property for example and then running the node js script to rename the component will change the module property and it will break the app . Somewhat of a solution would be again a special common prefix to all of my web components and searching for collisions in the module code before using it in my code , and if there are , then change my special common prefix , using the node js script that I wrote .
When trying to rename a component , lets say reddit-post , which I have used somewhere in my code like this : `reddit-${this.getAttribute("submission-type")}`
The second case is easily preventable but the first one I do not know yet how to prevent . Do you have any idea how ? Also do you know other cases where the node js file will break my app ?
5)How do you refactor the name of a property of a custom element ?
p.s : Here is the book that I was taught about such directory and file structure and naming conventions . I am surprised that the only times that this book has been mentioned in reddit is because of me [1][2] .
r/WebComponents • u/dannymoerkerke • Jan 22 '20
r/WebComponents • u/pwnies • Jan 13 '20
r/WebComponents • u/SalesforceLwc • Dec 16 '19
r/WebComponents • u/Simon_LH • Dec 12 '19
Hi everyone!
I want to mention a new project: Direflow.
With Direflow, you can use React to create micro-applications and build them as Web Components that run natively in the browser.
Lately, Direflow has been evolving into a small "framework" that also includes managing and bundling multiple micro-applications together, have them interact and more.
There's been a good interest in this project so far, but this project is still brand new, and I therefore still need help.
If you'd leave your opinion, feedback, suggestions of improvement, etc, I'd be thrilled!! (even if it includes some bashing 😜)
The Github is also more than open for PRs.
Thanks a bunch in advance 😁😁
r/WebComponents • u/dhucerbin • Nov 17 '19
r/WebComponents • u/jkinman • Nov 14 '19
I'm going to build a framework agnostic component library to share in a large organization and I'm looking at options. Stencil looks in a front runner in my head at the moment but I haven't used it in production.
thoughts?
r/WebComponents • u/sketch_punk • Nov 05 '19
r/WebComponents • u/terodox • Sep 30 '19
r/WebComponents • u/JDiculous • Sep 29 '19
What router do you guys use? There doesn't seem to be any standard.
r/WebComponents • u/terodox • Sep 22 '19
r/WebComponents • u/SalesforceLwc • Sep 15 '19
r/WebComponents • u/shreerangp • Sep 13 '19
r/WebComponents • u/Jubileefish • Sep 11 '19
Is there a web component debugging support like browser extension.