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.08k stars 1.56k forks source link

Need unique js library names #27339

Closed jmesserly closed 6 years ago

jmesserly commented 8 years ago

From @vsmenon on April 18, 2016 16:36

If I have: foo/index.dart:

main() => print('foo');

bar/index.dart:

main() => print('foo');

and I compile together, e.g.,:

dart bin/dartdevc.dart compile --modules node -o foobar.js foo/index.dart bar/index.dart

I end up with:

(function() {
  'use strict';
  const dart_sdk = require('dart_sdk');
  const core = dart_sdk.core;
  const dart = dart_sdk.dart;
  const dartx = dart_sdk.dartx;
  const index = Object.create(null);
  const index$ = Object.create(null);
  index.main = function() {
    return core.print('foo');
  };
  dart.fn(index.main);
  index$.main = function() {
    return core.print('bar');
  };
  dart.fn(index$.main);
  // Exports:
  exports.index = index;
  exports.index = index$;
})();

Note that the two exports at the end stomp on each other.

_Copied from original issue: dart-lang/devcompiler#504

jmesserly commented 8 years ago

From @vsmenon on April 18, 2016 16:38

@jmesserly Should we make the export name relative to some top-level? This should work nicely for packages (e.g., imagine foo and bar are directories under lib).

jmesserly commented 8 years ago

Hmmm, that's a tricky one. Relative paths are a tricky thing to get right: what is it relative to? For packages, we have an answer. Otherwise it's pretty hard. Maybe we can assume files are always in a "package structure" of some sort (either as part of Bazel setup or pubspec.yaml).

Once we have that figured out, there's the question of how we encode this in JavaScript. Do you want to use library names like src_fooindex? But "" is legal in Dart, so that could still collide. Maybe something like "angular.src.foo.index" is the right answer. As in:

let angular = require('angular');
let index = angular.src.foo.index;
let index$ = angular.src.bar.index;
jmesserly commented 8 years ago

Another problem we'll hit: what if I ask DDC to combine multiple packages together: dartdevc compile -o something.js package:foo/foo.dart package:bar/bar.dart. Is that supported, or not? If it is, how do we represent that?

If we can assert package == module, then we can instead treat these as essentially two JS modules, so it's invalid to compile them together. Instead this you need compile+link.

jmesserly commented 8 years ago

From @vsmenon on April 18, 2016 18:4

The . syntax looks nice. Are you concerned about perf with multiple levels of dereference? Any other characters work?

We could do this wrt a (passed in?) common dir. If that defaults to the package's lib directory, that works out nicely. If not, the user can set something else I suppose.

jmesserly commented 8 years ago

The . syntax looks nice. Are you concerned about perf with multiple levels of dereference? Any other characters work?

Hmm good question. Normally in JS properties any char is valid:

let angular = require('angular');
let index = angular['src.foo.index'];
let index$ = angular['src.bar.index'];
let index$ = angular['but "this" string really+could!be~anything... ☺'];

That said, ES6 export will restrict this to legal identifiers, I'm pretty sure. And there's also the question of to what extent we're matching/violating expectations on the JS side.

One downside of dotted names is how they look at the declaration side:

// it gets worse the more nested this is...
export const src = {
  foo: {
    index: index
  },
  bar: {
    index: index$
  },
};

They do look good at the usage sites though.

The dotted naming convention would be nice in Dart2, to be honest:

// instead of:
import 'package:angular/foo/index.dart';
import 'package:angular/angular.dart';
// do this:
import angular.foo.index;
import angular;

Another issue to sort out is conflicts:

import 'package:angular/src/index.dart';
import 'package:angular/src.dart';

What does "angular.src" refer to?

I'm not sure how to handle that. This needs some design for sure.

jmesserly commented 8 years ago

@vsmenon and I chatted about this ... here's our idea for a starting point:

jmesserly commented 8 years ago

We also have a problem with a few of our well known names like "dart" and "dartx" (and some packages, e.g. Analyzer do have library names like "dart.dart")

jmesserly commented 6 years ago

there are other issues tracking library-root improvements. "dart" and "dartx" have been fixed.