dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.21k stars 1.57k forks source link

Support requiring modules via JS module systems #25059

Open kasperpeulen opened 8 years ago

kasperpeulen commented 8 years ago

I'm trying to interop a modern javascript library with modules. It is a big library with like 20 modules

On the javascript site, they don't put those modules in the html, but use browsify or webpack. I have no clue how to write an interop for that.

http://prosemirror.net/doc/manual.html#bundling

To use ProseMirror in a web page, you first need to build your script using a module bundler. This library is distributed as a large number of small modules. This means you get a clean, modular interface, and only have to include the parts that you need. But it also means you can't just drop in a script tag and get going.

nex3 commented 7 years ago

I'm renaming this, since a number of broader issues have been merged into it and the old name was pretty narrowly-scoped.

jmesserly commented 6 years ago

https://github.com/dart-lang/sdk/issues/29808 has good discussion on this.

jmesserly commented 6 years ago

Related issue, but this one is about how we export a module for JS consumption, rather than import: https://github.com/dart-lang/sdk/issues/27692

CosmicPangolin commented 5 years ago

@jmesserly

Has there been any progress here? Been building a commercial app on angulardart, but losing many high quality js modules feels like a dealbreaker...I can’t figure out a reasonable workaround for necessary webgl libraries :/

jmesserly commented 5 years ago

Here's some JS interop examples: https://github.com/matanlurey/dart_js_interop#dart_js_interop

Could you explain more what you're trying to do with webgl? Are there any particular libraries you're trying to use?

CosmicPangolin commented 5 years ago

For sure - I'm using 2dimensions' Flutter runtime for a mobile app, and I want to use their webGL runtime in AngularDart to maximize code+asset reuse. See https://github.com/2d-inc/Nima-WebGL

That lib is littered with import/exports, including imports of external params from gl-matrix. My understanding was that interop couldn't currently handle this structure, and that I'd need to refactor all that code to make it play nice...buuut I could be missing something, since I'm pretty new at all this :)

jmesserly commented 5 years ago

You should be able to load that JS library as normal -- any imports/exports inside of JS code are fine. I believe webpack can create a single .js file that links everything together.

Then to use that library from Dart, you'd want to write a .dart file that contains the interfaces:

@JS('Nima')
library nima_webgl;

// note: Dispatcher class needs to be defined too
// it would be nice to add type annotations, especially for return types

@JS()
class Actor extends Dispatcher {
  external factory Actor();
  external addDependency(a, b);
  external sortDependencies();
  external addDirt(component, value, recurse);
  external update();
  external get root;
  external resolveHierarchy(graphics);
  external dispose(graphics);
  external initialize(graphics);
  external advance(seconds);
  external draw(graphics);
  external getNode(name);
  external getAnimation(name);
  external getAnimationInstance(name);
  external makeInstance();
  external computeAABB();
  external copy(actor);
}

Similar thing for any other public classes. That makes Dart aware of the JS classes, so you can use them.

Aetet commented 5 years ago

@jmesserly Hey. Could you provide repo with predefined webpack+js_interop with ES modules?

jmesserly commented 5 years ago

I don't know how to use webpack, sorry! They do have documentation: https://webpack.js.org/concepts/, maybe that will help get you started.

MikeMitterer commented 5 years ago

@jmesserly Have you ever tried to use one of the top JS libs in Dart? That's one of Dart's weakest points...

jmesserly commented 5 years ago

Yeah, totally. It's less than ideal (to put it mildly). I'm working on making that better.

I would like to spend some time thinking about integration with JS module bundlers and build systems too (to address @Aetet's point above). But first, I want to address the core features of interoperability: being able to nicely express and use JS APIs in Dart and vice versa.

nex3 commented 5 years ago

While it's possible to work around this by treating require() like a global function and assigning it to self as in node_preamble, this causes problems with downstream tools (see https://github.com/sass/dart-sass/issues/726). Built-in Dart support would be much better.

knownasilya commented 5 years ago

This is becoming more of an issue as browsers have implemented modules and more browser libraries are moving to modules instead of globals. More and more library authors are no longer shipping global builds of their libraries. Along with node's new .mjs file format, this is no longer a fringe case.

ghost commented 4 years ago

@knownasilya did you have success with a webpacked library? I transpile Typescript with webpack to a single bundle.min.js then All I get is

TypeError "dart.global.MyClass" is not a constructor

tried this: https://stackoverflow.com/questions/52276662/using-dart-js-interop-with-es6-classes

with no success, Dart do not see my MyClass Problem is that I have no working example of how to make the MyClass "global" after being webpacked

EDIT: ok I think I got it