Is there a way to check if the script is running in the dart vm or dart2js?

北城余情 提交于 2020-01-03 09:05:08

问题


Is there a way to check if the script is running in the dart vm or dart2js? Maybe using mirrors API?


回答1:


There is no official way, as far as I know. The intent is that for all practical purposes, you shouldn't have to know if you are running native or compiled to JavaScript.

That said, there are few hacks you can use. The easiest one is probably to exploit the fact that Dart has two numeric types, int and double, while JavaScript has only one, which is equivalent to Dart's double, and dart2js doesn't have a special implementation of int just yet. Therefore, identical(1, 1.0) is false in Dart, and the VM implements that correctly, but when compiled to JS, it is true.

Note that you should think pretty hard before using a hack like this. In most cases, you don't have to do that, just write Dart and don't try to recognize if you are running JS or not. Also, noone can guarantee that it will work forever.




回答2:


Based on a code fragment found in path library (Dart v0.7.2) :

import 'dart:mirrors';

/// Value indicating that the VM is Dart on server-side.
const int DART_SERVER=1;

/// Value indicating that the VM is Dart on client-side.
const int DART_CLIENT=2;

/// Value indicating that the VM is JavaScript on client-side (e.g. dart2js).
const int JS_CLIENT=3;

/// Returns the type of the current virtual machine.
int vmType() {
  Map<Uri, LibraryMirror> libraries=currentMirrorSystem().libraries;
  if(libraries[Uri.parse('dart:io')]!=null) return DART_SERVER;
  if(libraries[Uri.parse('dart:html')]!=null) return DART_CLIENT;
  return JS_CLIENT;
}

/// Application entry point.
void main() {
  print(vmType());
}



回答3:


Another very hacky way to for a script to tell if is running in the server side VM vs the client side is to use the Options class.

The following app (file called myapp.dart) prints different output when run on the command line VM or in the browser:

void main() {
  var options = new Options();
  print(options.arguments);
  print(options.executable);
  print(options.script);
}

Command line output:

[]
C:\work\dart\editor\dart\dart-sdk\bin\dart.exe
myapp.dart

In-browser output:

[]
     <-- empty string
     <-- empty string

The in-browser output is the same, though, whether it's running in a Dart browser VM or as JS.




回答4:


Since dart.js transforms scripts .dart to .dart.js, this works :

bool _isDart() => document.getElementsByTagName("script").where((s) => s.src.endsWith(".dart.js")).isEmpty;



回答5:


I've been thinking about this, and actually, there is a way to discover if the browser has support for Dart (which is almost the same thing) using navigator.webkitStartDart. This is what the dart.js file that bootstraps Dart uses, when determining if the browser supports dart natively, so we can use JavaScript interop to do the same thing.

The following app returns true if running in Dartium, but false if running in Chrome or Firefox:

import 'dart:html';
import 'package:js/js.dart' as js;

void main() {
  print("Is Dart? = ${isDart()}");
}

bool isDart() => js.scoped(() {
  try {
    // will throw exception if it doesn't exist
    var dartExists = js.context.navigator.webkitStartDart;
    return true;
  }
  on NoSuchMethodError {
    return false;
  }
});

Your pubspec will need to look something like this:

name: webkitstart
description: A sample web application
dependencies:
  browser: any
  js: any

@Ladicek's caveat on another answer is still valid though:

In most cases, you don't have to do that, just write Dart and don't try to recognize if you are running JS or not.

Update - This solution doesn't actually tell if the script is running in browser-based dartvm, only that the dartvm is available in the browser. However, if you deploy your app with the standard script tags including packages/browser/dart.js - then this will ensure that if the browser has the dart-vm, it will start the app in the dart-vm. You would only get the app running in javascript if you explicitly linked only the .dart.js version of your app and removed the reference to the dart.js script

ie, This:

<!-- will use dart-vm if available, fallback to JS if not -->
<script type="application/dart" src="example.dart"></script>
<script src="packages/browser/dart.js"></script>

versus this:

<!-- will only use JS, even if dart vm is available -->
<script type="application/dart" src="example.dart.js"></script>


来源:https://stackoverflow.com/questions/14655084/is-there-a-way-to-check-if-the-script-is-running-in-the-dart-vm-or-dart2js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!