Giter Site home page Giter Site logo

Comments (5)

chadams avatar chadams commented on July 17, 2024 2

After more thought I completely agree, it's easy to add externally to facet with something like...

     function init(url) {
        return fetch(url)
          .then((response) =>
            response.ok ? response.text() : Promise.reject(Error(url))
          )
          .then((template) => {
            let templateElement = document.createElement("template");
            templateElement.innerHTML = template;
            template = templateElement.content;
            facet.discoverDeclarativeComponents(template);
          });
      }

This actually works on a HTML page with many facet templates. pretty cool

from facet.

kgscialdone avatar kgscialdone commented on July 17, 2024 1

Facet's currently available way of doing single-file components looks something like this:

let exampleComponent = document.createElement('template')
exampleComponent.innerHTML = `
  <p>Hello, <slot>world</slot>!</p>
`
facet.defineComponent('example-component', exampleComponent, 
  { /* Options normally parsed from attributes on the template element */ })

Understandably this is less than ideal, but - given that the intended way of defining components in Facet is in HTML - it's the best I can do at the moment without bloating the file with additional utility methods to support a nicer syntax that I don't even want people to use. Hence the idea of doing imports like above.

To give you an idea of the implications of implementing this, here's a rough example of what it would probably look like in the source code:

// This would run before the current initial load process
// Initial load would then await `Promise.allSettled(importRequests)`

let importRequests = []

for(let url of document.currentScript?.getAttribute?.('import')?.split?.(/\s/) ?? [])
  importRequests.push(fetch(url)
    .then(res => res.text())
    .then(def => {
      let definitions = document.createElement('div')
      definitions.innerHTML = def
      this.discoverDeclarativeComponents(definitions)
    })
  )

The biggest difficulty with implementing this is that due to the asynchronous nature of importing the definitions, we're essentially left with two options:

  • Local component definitions are delayed by imported definitions
  • Local component definitions run before imported definitions, and thus cannot use imported mixins without a workaround

Obviously, neither of these are ideal, but in the example above I've chosen to go with the former for hopefully understandable reasons. With that said, I'm somewhat of the opinion that client-side component imports are an anti-pattern for Facet in the first place, so I'm unsure whether to implement this; even if it is implemented, it would come with a strong recommendation to use server-side includes from local component files instead in production, which makes me all the more hesitant to offer it as a feature in the first place if I don't want to recommend using it.

Also note the lack of security measures; the policy on this would be "use a CSP".

from facet.

kgscialdone avatar kgscialdone commented on July 17, 2024 1

The more I consider this, the more I lean towards "out of scope". Single-file components are, in my opinion, an antipattern to begin with, and adding additional complexity to Facet (however small) to enable them when I don't even think people should be using them to begin with would be an irresponsible choice as a library developer. Facet already gives you the tools to create them if you choose to, but those tools are intentionally not very ergonomic for exactly the same reason: to discourage using them unless absolutely necessary.

I may reconsider later, but for now I'm closing this as "won't add". Thanks for your input and support!

from facet.

kgscialdone avatar kgscialdone commented on July 17, 2024

I've considered some ways to handle this, and whether or not to do so at all. While single-file components are convenient for development, when implemented client-side they also generally reduce the quality of the user experience due to longer delays before components are fully loaded, so I'm conflicted on whether to do so or not.

With that said, my current idea for syntax to do so is as follows, and I would welcome opinions on it. The three given examples would be for a local component, a remote component, and a shortcut for a remote component from a theoretical Facet component library site (shorthand names of which would need to be registered).

<script src="facet.min.js"
 import="./components/example-component.html
         https://facet.unmodernweb.com/library/remote-component.html
         library-name:published-component"></script>

from facet.

ADAMC133 avatar ADAMC133 commented on July 17, 2024

This looks pretty good. would it resolve all the imports before creating the components?

I'm just thinking of how one would easily share custom elements. For example, a UI library across multiple projects. One thought is just returning the templates in a HTMX like environment, but they don't automatically get picked up without calling facet.discoverDeclarativeComponents(document); afterwards. any "import" would need to do the same. Which is fine, but might trip up some developers.

Fetching HTML might mean passing a string to defineComponent and defineMixin, which doesn't sound great. Even if you created another function, now you would have to parse to see if it's a component or mixin. Might be easier to just innerHTML the fetched HTML somewhere. call discoverDeclarativeComponents and then remove the element? I don't know...just thinking about it.

from facet.

Related Issues (2)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.