Skip to content
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

How come we don't need to register a component when we import it? #4

Open
luc4leone opened this issue Dec 29, 2021 · 3 comments
Open

Comments

@luc4leone
Copy link

Hi Ben,

I did not expect listing 5.7 to work, because in strings.js we are not registering the component WebHarpString. We are importing WebHarpString

import WebHarpString from "../string/string.js";

but we are not registering it

customElements.define('webharp-string', WebHarpString);

Instead it works! How?

For example, when in index.html we run

<script type="module" src="./components/app/app.js"></script>

we are "importing" the entire app.js code, which include the registration of the WebHarpApp component,

customElements.define("webharp-app", WebHarpApp);

so, in index.html I would expect

<webharp-app strings="8"></webharp-app>

to work just fine. While the code in strings.js so far for me, it's magic ☺️


PS: not important: in app.js I don't think we need to export default the class WebHarpApp

export default class WebHarpApp extends HTMLElement { //...

since with the script tag in index.html

<script type="module" src="./components/app/app.js"></script>

we are taking in the entire module, right?

@bengfarrell
Copy link
Owner

Hi Luca! I don't have my book handy right now, but I'm looking over the source code in this repo.
So one thing that might be confusing is that yes, we are indeed just importing the WebHarpString class. Inside the module contained there, at string.js there is a line of code which states:

if (!customElements.get('webharp-string')) { customElements.define('webharp-string', WebHarpString); }

You might be thinking that, "well, we're only importing the class, so this code wouldn't get run", but that's not true! Any code in a module will run, and it's called a module "side effect". Try just putting a console.log in this strings.js module outside of the class. Just by importing the module, it'll run and you'll see the log in your dev tools. Likewise - defining that webharp-string will also run. You can even think of the class definition code itself as running even if you don't import/export it. The code is run and a class is defined - this definition of the class could also be a "side effect" that happens, but of course the class won't get instantiated or used unless something extra happens, either its exported and used, or we define a component with it as we do here.

Again, haven't looked at this code in ages, but honestly I'm not seeing a need to use the full import as I wrote it:
import WebHarpString from "../string/string.js"

It could really be:
import "../string/string.js"

The reason for that is that all we need is for those side effects to run. We're not using the WebHarpString class exported reference at all, just expecting that the component is defined by that module so we can use it.

Anyway, it's pretty typical for a Web Component to self-define by using the module side effects like this.

And yes! I think you are correct on that last point:

export default class WebHarpApp extends HTMLElement {... could simply become
class WebHarpApp extends HTMLElement {... because this module (the main application module) also self-defines as a Web Component.

Hope that helps!

@luc4leone
Copy link
Author

You might be thinking that, "well, we're only importing the class, so this code wouldn't get run", but that's not true!

That's exactly what I was thinking! Ahah

Thanks for the explanation Ben, now all is clear. I didn't know about "import side effects" and I didn't think about the console.log experiment. By the way, I like the way you do experiments in the book also. I am trying to learn from your approach.

@bengfarrell
Copy link
Owner

So glad you're enjoying! Thanks for the compliments 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants