Skip to content

A proposal for @JS interop with module loaders #29808

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

Closed
dam0vm3nt opened this issue Jun 7, 2017 · 5 comments
Closed

A proposal for @JS interop with module loaders #29808

dam0vm3nt opened this issue Jun 7, 2017 · 5 comments
Labels
closed-duplicate Closed in favor of an existing report type-enhancement A request for a change that isn't a bug web-js-interop Issues that impact all js interop

Comments

@dam0vm3nt
Copy link

dam0vm3nt commented Jun 7, 2017

Following #25059 this is my proposal:

Dart

Add a new library level annotation to package:js like @JSDependencies to be used to indicate the js dependencies like so :

@JS('namespace')
@JSDependency(['mod1','mod2'])
library mylib;

import `package:otherpkg/lib.dart`;

...

DDC

The previous snippet is currently translated like so:

define(['dart_sdk','packages/otherpkg/lib__lib'],function(dart_sdk,pkg) {
 ...
});

With the introduction of @JSDependencies the same snippet should become :

define(['dart_sdk','packages/otherpkg/lib__lib','mod1','mod2'],function(dart_sdk,pkg) {
 ...
});

This would allow to preload some other native modules before the current package. Those modules could define symbols in the global namespace or implements other loading mechanismo by means of requirejs plugin (example : htmlimport!/natve/lib/path, where htmlimport is a requirejs plugin for importing html in the current dom using html import.

Dart2js

(for completeness)

For dart2js the same annotation could generate some preload code that adds <script src='mod1'> in the current dom at startup for example (or transforms the entry-point html in order to inject them and be sure that the dependencies are loaded when dart start execution ...).

Another possibility is to leverage some sort of loader mechanism. I don't know dart2js architecture so well to know where to inject that code but I think it shouldn't be so difficult to achieve. This could also be combined with deferred loading in order to cope with the async nature of loading external dependencies.

Notes:

I've considered a list of dependencies but actually ony one would suffice that in turns could load other dependencies too.

The same result could be achieved adding a named optional attribute to @JS annotation avoiding introducing a new annotation.

@vsmenon vsmenon added web-js-interop Issues that impact all js interop type-enhancement A request for a change that isn't a bug web-dev-compiler labels Jun 7, 2017
@dam0vm3nt
Copy link
Author

@vsmenon would you consider any PR about this feature if ever I was able to make one (for DDC expecially) ?

@vsmenon
Copy link
Member

vsmenon commented Jun 9, 2017

@jacob314, @jmesserly - thoughts?

@jmesserly
Copy link

Having a means to import JS modules from Dart is essential. I think dart2js is the hard part, though. It will be very easy to implement in DDC.

Feature design thoughts. Thinking in terms of ES6 module imports, there's two parts: the module URL (usually path) to import, and name(s) that are imported (either the name to use for the module object, or the name(s) that are imported from the module). Presumably if we're importing the module, we also need to access something from it.

Also I would probably call it @JSImport and have it take a single module path, to match ES6 module terminology/syntax as closely as possible.

For reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

I think that would leave us with something akin to:

@JSImport('./foo')
dynamic _foo; // this can be whatever name you want

@JSImportFrom('./foo')
dynamic bar, baz; // import these names from "foo"

@JSImportFrom('./foo', ['reallyLongName', 'anEvenLongerName'])
dynamic _bar, _baz; // import the above names from "foo" and rename them

@JSImportFrom('./foo')
class C { C(); } // allows `dynamic d = new C();` then calling methods on it

@dam0vm3nt
Copy link
Author

My proposal was trying to extend the existing @JS interop instead of defining a different API. @JSImport in this sense its very similar to @JS with the addition of the module indication. So I was thinking about something more similar to :

@JS('reallyLongName', from:'foo')
external var bar;

or

@JS('reallyLongName')
@JSFrom('foo') // or @JSDependency('foo') like in the initial proposal
external var bar;

I would use a "module id" that is agnostic of the actual undelying module system leaving the task to compiler to translate that to the module loader effectively used.

@jmesserly
Copy link

merging this into #25059 ... I'll add a link there because this has good discussion

@jmesserly jmesserly added the closed-duplicate Closed in favor of an existing report label Jun 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-duplicate Closed in favor of an existing report type-enhancement A request for a change that isn't a bug web-js-interop Issues that impact all js interop
Projects
None yet
Development

No branches or pull requests

3 participants