5 ms·
is there any reason you can't write a web component with a <style> block, a <script> block, and a bunch of html? the wedging everything into js is messy, to sa
by clairity 6y ago
is there any reason you can't write a web component with a <style> block, a <script> block, and a bunch of html?
the wedging everything into js is messy, to say the least. it seems the main benefit is being reusable and tightly scoped, but with randomized class names, you could tightly scope the aforementioned bundle as well. even better would be if html added 'for' attributes to <style> and <script> tags, like labels have, so you could target nodes in the dom by id.
perhaps being composable is a bigger challenge, but is it insurmountable with this approach?
- olex 6y agoThis is exactly how vue.js "single file components" work - a <template> with the "bunch of html", <script> and optional <style> blocks.
- clairity 6y agothat's pretty close to what i'm thinking of, but still has some limitations (from https://vuejs.org/v2/guide/single-file-components.html https://vuejs.org/v2/guide/single-file-components.html): • Global definitions force unique names for every component • String templates lack syntax highlighting and require ugly slashes for multiline HTML • No CSS support means that while HTML and JavaScript are modularized into components, CSS is conspicuously left out • No build step restricts us to HTML and ES5 JavaScript, rather than preprocessors like Pug (formerly Jade) and Babel
- shhsshs 6y agoYou may be misunderstanding (or I’m not understanding your intent). Single-file components were made specifically to overcome those issues, as mentioned on the page you linked.
- clairity 6y agoapologies, i did misread the page i quoted from. it does seem like i need to explore these single-file vue components more.
- eeJah9to 6y agoYou can, using the template element: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template https://developer.mozilla.org/en-US/docs/Web/HTML/Element/te... I tried that for webcomponents, but I found more to my taste to actually have everything in my javascript file rather than to jump between files (it's not that messy if you keep your components smalls).
- clairity 6y agoneat, i remember running across that a while back, but promptly forgot about it. thanks for the reminder!
- Izkata 6y agoI experimented with this some years ago, building my own mini-framework for components. The main system provided a global hook that javascript within the template file could attach itself to, so everything for a single component did exist in a single file. So it is doable. (I liked that part of my system, but I'd rewrite about half of it if I wanted to use it again)
- crooked-v 6y agoTwo big points: a. You can treat it as 'just Javascript' when dealing with bundlers (both complicated stuff like Webpack and simple hacky things like Gulp script concatenation). b. For JSX and similar variants, because even the template part is 'just Javascript' with semantic sugar for tags, you can statically analyze it in a way that you can't with separate HTML and script content.
- ragerino 6y agoProblem here is CSS, JavaScript, and HTML. You might use variables, functions or attributes, styles, tags, that would interfere with other components. That's why you want an additional layer like Angular2+ taking care of that.
- clairity 6y agoyes, that's the scoping issue i mentioned, which can be solved other ways, like with admittedly-not-ideal randomized classes (or 'for' attributes, perhaps with css-style selectors rather than just for id's).
- RivieraKid 6y agoThat's what Svelte does. I can't recommend this framework enough, it's easy to learn, simple, fast and small.
- Ciantic 6y agoIf you want single file components, you should look at the Svelte ( https://svelte.dev/ https://svelte.dev/ ). It also compiles the framework away, which is the reason it appears very high on that list when it comes to size.
- clairity 6y agocool, i peeked at svelte when it was posted about on hn before, and liked what i saw in the few minutes i spent on it. i should take a deeper look.
- edoceo 6y agoRiotJS does this too
- werdnapk 6y agoSee the svelte and vuejs examples for what you describe.
- rishav_sharan 6y agoI tried that using <template> <style> blocks, a few years ago. my biggest problem was simply that I still had to add all my templates to a single long html file. And that really feels suboptimal. I had a scaffolded page structure at top. and then dozens of template sections following it. and then as some templates are supposed to call other templates (form inside page section) there was a clear hierarchy but my html file was flat and it was getting harder to reason about the structure of my app the more templates I added. I finally threw it all away and just did a vanillajs spa. I really wanted to be able to breakup my html file into smaller composable ones without having to do that in JS. but there is no current solution for html importing other html files, and the spec discussion around html import are pretty much dead in the water (and have been since 2013)
- clairity 6y agothanks for sharing your experience, and agreed that being able to compartmentalize in separate, composable files is a desirable feature.
- orange8 6y ago> my biggest problem was simply that I still had to add all my templates to a single long html file. The alternative (atleast when using frameworks like React and Vue with packagers like webpack is having it all in a single long html file. Which is just shifting markup from html to js. The other alternative is to dynamically load the html via ajax calls. > I had a scaffolded page structure at top. and then dozens of template sections following it. and then as some templates are supposed to call other templates (form inside page section) there was a clear hierarchy but my html file was flat Here you could make use of the document.ready event, and a js script that automatically parses and saves all <template> tag by id. That way, the templates calling other templates have a single source of truth for all dependent templates. You could also combine this will lazy loading via ajax calls. > I really wanted to be able to breakup my html file into smaller composable ones without having to do that in JS. but there is no current solution for html importing other html files There is no getting around JS if you want client side dynamic rendering - that's what its for. HTML is for static content, css for styling, JS for everything else.
- c17r 6y agoSaw this idea on a previous HN comment thread and was intrigued by the idea.
- ww520 6y agoYou can use @import to include shared CSS files. HTML import is still pending in the standard committee; should come soon. For now HTML template needs to go with the Javascript. I usually structure a component like the following. The nice thing about WebComponent is everything is scoped to the component and you can have pretty generic names for things except the defined component name ("component1" in this case). /components/component1.js import cu from "/util/comp-util.js"; import comp2 from "/components/component2.js"; import comp3 from "/components/component3.js"; (function() { let template = ` <template> <style> @import "/styles/shared.css"; @import "/components/component1.css"; </style> <div id="the_component" class="component1"> <button /> <component2 attr1="green" attr2="10" ... /> <component3 ... /> ... </div> </template>`; class ComponentElement extends HTMLElement { constructor() { super(); cu.attachTemplate(this, templete); // the attachment boiler-plate code in util. } ... } window.customElements.define("component1", ComponentElement); }());
- clairity 6y agointeresting, i look forward to when html imports come about. it's strange that this most fundamental component weren't among the first things you could import (i guess plain old links subsumed some of that need).
- cletusw 6y agoHTML Imports were actually among the first (shipped in Chrome), but then ES Modules/import/export took off and now spec authors want to reconcile the two before standarizing.