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

Importing native js modules for side effects only #4156

Open
uosis opened this issue Aug 21, 2020 · 4 comments
Open

Importing native js modules for side effects only #4156

uosis opened this issue Aug 21, 2020 · 4 comments

Comments

@uosis
Copy link

@uosis uosis commented Aug 21, 2020

There does not appear to be a way to do the JS equivalent of import 'foo'; in Scala.js. Our workaround is this pattern:

  @js.native
  @JSImport("@material/mwc-button", JSImport.Default)
  object RawMwcButton extends js.Object

  private val dummy = RawMwcButton

If we don't have the dummy variable, object gets optimized out and import never happens.

Is there / should there be a better way to do this?

@sjrd
Copy link
Member

@sjrd sjrd commented Sep 6, 2020

You don't necessarily need a dummy variable. It's OK to only refer to the object as a statement, for example in your main or in the constructor body of a class/object that relies on that functionality. In other words, wherever you put the

private val dummy = RawMwcButton

you can equally write just

RawMwcButton

There is no better way to do this. Since Scala.js only reaches external imports for things that are themselves reachable, you need to make sure that the object is somehow reachable.

AFAICT, it's also not really possible to change Scala.js to make this any different. Much of the specification relies on having no real entry points besides main methods and exports. We do have the notion of static initializers, which are "out of the blue" entry points, so there is precedent for adding other kinds of entry points. But adding a different kind @JSImport that would automatically reach its target module if it is on the classpath would behave very differently from the other @JSImports, and for that there is no precedent.

@gzm0
Copy link
Contributor

@gzm0 gzm0 commented Sep 7, 2020

Could we allow local native objects/classes so that this can be hidden away? (maybe even with a macro library)?

def loadMwc(): Unit = {
   @js.native
   @JSImport("@material/mwc-button", JSImport.Default)
   object RawMwcButton extends js.Object

  RawMwcButton
}
@sjrd
Copy link
Member

@sjrd sjrd commented Sep 7, 2020

It can already be hidden away by making it private in a companion object or something like that. It doesn't have to leak into the public API.

@gzm0
Copy link
Contributor

@gzm0 gzm0 commented Sep 7, 2020

Ah, fair enough. Although that wouldn't work with a def macro. But not sure that is actually necessary.

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

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.