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
First Shadow DOMd webcomponent #6
Conversation
Should Sent with GitHawk |
I don’t think so. We are using webpack to bundle it all which is all done in a dev environment. Moving it out of |
Web Components SSRServer-side rendering of Web Components is possible, however, it is not as common or straightforward as React, Ember, Vue, or Angular. The most documented way to do this is with I think your main point though, is wanting to ensure
To that end this was my plan for the web components. Create a <candidate-card name="pete-buttigieg">
<img class="candidate-image" src="/assets/images/pete-buttigieg.jpg" alt="Portrant of Pete Buttigieg.">
<div class="candidate-meta"><h2 style="margin: 0; padding: 0;">Pete Buttigieg </h2>
<p style="margin: .25rem 0; font-size: 1.25rem; font-weight: 500;">Delegate count:
23</p>
</candidate-card> The children of class CandidateCard extends Component {
...
template() {
return h('slot');
}
...
} This will ultimately result in the following DOM being produced on the client <candidate-card name="pete-buttigieg">
#shadow-root
<slot> pointer to the img, div, p nodes </slot>
/shadow-root
<img class="candidate-image" src="/assets/images/pete-buttigieg.jpg" alt="Portrant of Pete Buttigieg.">
<div class="candidate-meta"><h2 style="margin: 0; padding: 0;">Pete Buttigieg </h2>
<p style="margin: .25rem 0; font-size: 1.25rem; font-weight: 500;">Delegate count:
23</p>
</candidate-card> I've already shown today that shipping markup containing a custom element is ultimately just rendered as a "div". Which means that this slotting strategy will fulfill what I believe the two goals are for the default display of the candidate information. What then does Web Components buy us? Well it provides for encapsulation of the hover/click behavior of #5 and a strategy to leverage browser native components for rich client-side interaction and behavior. (It is also an excuse to use them) If the additional data and interaction must be fully SSR, we may want to change this strategy. Options include, not using Shadow DOM and attempting SSR or abandoning web components. I will also note, that JSDOM has finished support for Custom Elements after having an open issue for 4 years this past weekend. So the SSR story may be getting better. |
if (showDetails) { | ||
return h('div', 'Details'); | ||
} | ||
return h('slot'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If reading through the SSR note, you ask why are we slotting at all, here is the beginning of the plan. Slot the initial/default display, but then replace that when the user interacts with the card. So basically the "details" wouldn't be SSR'd but the normal view is.
package.json
Outdated
@@ -1,14 +1,32 @@ | |||
{ | |||
"name": "1990towin", | |||
"scripts": { | |||
"start": "NODE_ENV=dev nodemon -w ./ -e css,js,json,html ./server/index.js" | |||
"start": "NODE_ENV=dev nodemon -w ./ -e css,js,json,html ./server/index.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The script start
is only used in dev, so it's fine to remove it if dev
becomes the default script. Or move the contents of dev
into start. Whatever is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the dockerfile to call start and updated the start
command
@@ -0,0 +1,22 @@ | |||
export function safelyDefine( | |||
elementName: string, | |||
customElement: CustomElementConstructor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get an error here, maybe because CustomElementConstructor
is not pulled in from anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is an interface from the dom
library specified in the tsconfig.json
, it shouldn't error for you 😞
const { extname } = require('path'); | ||
|
||
const shutdown = require('./shtudown'); | ||
const shutdown = require('./shutdown'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤷♂
5fbac6b
to
af4e4e3
Compare
This is the first web component that does nothing but
slot
the server markup. It ensures we have the proper build pipeline configured. It configures both a docker build pipeline using stage builds and webpack for compiling the client side code.It creates a new
dev
npm script that will start in parallel both the existingnodemon
functionality and awebpack
process in watch mode. It still requires the developer to manually reload to see their changes.